Setup

Load Packages

##Install Packages if Needed
if (!require("ggplot2")) install.packages("ggplot2")
if (!require("effectsize")) install.packages("effectsize")
if (!require("emmeans")) install.packages("emmeans")
Loading required package: emmeans
if (!require("dplyr")) install.packages("dplyr")
if (!require("tidyr")) install.packages("tidyr")
Loading required package: tidyr
if (!require("Rmisc")) install.packages("Rmisc")
Loading required package: Rmisc
Loading required package: plyr
----------------------------------------------------------------------------------
You have loaded plyr after dplyr - this is likely to cause problems.
If you need functions from both plyr and dplyr, please load plyr first, then dplyr:
library(plyr); library(dplyr)
----------------------------------------------------------------------------------

Attaching package: ‘plyr’

The following objects are masked from ‘package:dplyr’:

    arrange, count, desc, failwith, id, mutate, rename, summarise,
    summarize
if (!require("ggpubr")) install.packages("ggpubr")
Loading required package: ggpubr

Attaching package: ‘ggpubr’

The following object is masked from ‘package:plyr’:

    mutate

The following object is masked from ‘package:cowplot’:

    get_legend
if (!require("cowplot")) install.packages("cowplot")
if (!require("gridGraphics")) install.packages("gridGraphics")
Loading required package: gridGraphics
Warning: package ‘gridGraphics’ was built under R version 4.3.2Loading required package: grid
if (!require("tidyr")) install.packages("tidyr")

##Load Packages
library(ggplot2) #Required for plotting
library(effectsize) #Required for eta_squared effect sizes
library(emmeans) #Required for pairwise comparisons
library(dplyr) #Required to seperate columns in dataframe
library(tidyr) #Required for data organization
library(Rmisc) #Required for summarySE for summary statistics
library(ggpubr) #Required for adding pairwise p-values to plots with stat_pvalue_manual 
library(cowplot) #Required for arranging ggplots 
library(gridGraphics) #Required for adding labels to arranged plots
library(tidyr) #Required for reshaping datafrom from a wide to long format.

Note: Run “Graphing Parameters” section from 01_ExperimentalSetup.R file

Load and Organize Data

Note: Full Data with Bleaching Metrics and Color Scores created in 04_Models.R file

#Load Data
FullData<-read.csv("Outputs/FullData.csv", header=TRUE)


#Set factor variables 
FullData$TimeP<-factor(FullData$TimeP, levels=c("W2", "M1", "M4"), ordered=TRUE)
FullData$Site<-factor(FullData$Site, levels=c("KL", "SS"), ordered=TRUE)
FullData$Genotype<-factor(FullData$Genotype, levels=c("AC10", "AC12", "AC8"), ordered=TRUE)
FullData$Treatment<-factor(FullData$Treatment, levels=c("Control", "Heat"), ordered=TRUE)
FullData$Treat<-factor(FullData$Treat, levels=c("C", "H"), ordered=TRUE)
FullData$Seas<-factor(FullData$Seas, levels=c("Summer1", "Summer2", "Winter"), ordered=TRUE)

Percent Retention

Subset Thermal Assay Data by Treatment

##Control
FullData_C<-subset(FullData, Treat=="C")

##Heated
FullData_H<-subset(FullData, Treat=="H")

Calculate Percent Retention

Calculating retention as proportion remaining relative to corresponding control levels (0-1) for each site and genotype at each timepoint.

##Calculate averages for Control Treatment for each Site, Genotype, Timepoint, and Season
names(FullData_C)
 [1] "ID"          "RandN"       "TimeP"       "Site"        "Genotype"   
 [6] "Treat"       "Treatment"   "Seas"        "Set"         "Score_Full" 
[11] "Score_TP"    "SA_cm2"      "Chl_ug.cm2"  "Sym10.6_cm2"
FullData_C.a<-aggregate(FullData_C[,c(10:11, 13:14)], list(FullData_C$Site, FullData_C$Genotype, FullData_C$TimeP, FullData_C$Seas), mean, na.action = na.omit)
names(FullData_C.a)[1:4]<-c("Site", "Genotype", "TimeP", "Seas")
names(FullData_C.a)[5:8]<-paste(names(FullData_C)[c(10:11, 13:14)], "C", sep="_")

##Merge Control Averages with Heated Samples
#Merges by Site, Genotype, Timepoint, and Season
TolData<-merge(FullData_H, FullData_C.a, all.x=TRUE )

##Calculate Proportion Retained for each Bleaching Metric relative to Control
TolData$Score_Full.prop<-round((TolData$Score_Full/TolData$Score_Full_C), 4)
TolData$Score_TP.prop<-round((TolData$Score_TP/TolData$Score_TP_C), 4)
TolData$Chl.prop<-round((TolData$Chl_ug.cm2/TolData$Chl_ug.cm2_C), 4)
TolData$Sym.prop<-round((TolData$Sym10.6_cm2/TolData$Sym10.6_cm2_C), 4)

##Set values >1 to 1
TolData$Score_Full.prop[which(TolData$Score_Full.prop>1)]<-1.0000
TolData$Score_TP.prop[which(TolData$Score_TP.prop>1)]<-1.0000
TolData$Chl.prop[which(TolData$Chl.prop>1)]<-1.0000
TolData$Sym.prop[which(TolData$Sym.prop>1)]<-1.0000

##Create Site and Genotype Variable
TolData$Site.Geno<-paste(TolData$Site, TolData$Genotype, sep="_")

Subset by Timepoint

TolData_W2<-subset(TolData, TimeP=="W2")
TolData_M1<-subset(TolData, TimeP=="M1")
TolData_M4<-subset(TolData, TimeP=="M4")

Thermal Tolerance Chlorophyll

Full Set

Run Model

##Check normality
hist(TolData$Chl.prop)

shapiro.test(TolData$Chl.prop)

    Shapiro-Wilk normality test

data:  TolData$Chl.prop
W = 0.97395, p-value = 0.165
#Normal

##Model as a function of Site and Genotype and Timepoint
Tol_Chl_lm<-lm(Chl.prop~Site+Genotype+TimeP+ Site:Genotype + Site:TimeP + Genotype:TimeP, data=TolData)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Chl_lm)))


#Q-Q plot
qqnorm(resid(Tol_Chl_lm)); qqline(resid(Tol_Chl_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Chl_lm), resid(Tol_Chl_lm))

Model Results

#Model Results
summary(Tol_Chl_lm)

Call:
lm(formula = Chl.prop ~ Site + Genotype + TimeP + Site:Genotype + 
    Site:TimeP + Genotype:TimeP, data = TolData)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.127060 -0.031006 -0.004219  0.036829  0.097690 

Coefficients:
                     Estimate Std. Error t value Pr(>|t|)    
(Intercept)         0.2100753  0.0065828  31.913  < 2e-16 ***
Site.L             -0.0093229  0.0092942  -1.003 0.320289    
Genotype.L         -0.0980285  0.0111500  -8.792 5.31e-12 ***
Genotype.Q         -0.0467859  0.0116301  -4.023 0.000180 ***
TimeP.L             0.0638187  0.0112994   5.648 6.22e-07 ***
TimeP.Q             0.0464233  0.0115033   4.036 0.000173 ***
Site.L:Genotype.L   0.0003917  0.0157685   0.025 0.980272    
Site.L:Genotype.Q   0.0592529  0.0164183   3.609 0.000673 ***
Site.L:TimeP.L     -0.0528050  0.0159798  -3.304 0.001694 ** 
Site.L:TimeP.Q     -0.0236749  0.0161894  -1.462 0.149435    
Genotype.L:TimeP.L  0.0406686  0.0194339   2.093 0.041093 *  
Genotype.Q:TimeP.L -0.0627603  0.0196595  -3.192 0.002354 ** 
Genotype.L:TimeP.Q  0.0800244  0.0191901   4.170 0.000111 ***
Genotype.Q:TimeP.Q -0.1328570  0.0206170  -6.444 3.28e-08 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.05393 on 54 degrees of freedom
  (1 observation deleted due to missingness)
Multiple R-squared:  0.8229,    Adjusted R-squared:  0.7803 
F-statistic:  19.3 on 13 and 54 DF,  p-value: 8.612e-16
anova(Tol_Chl_lm)
Analysis of Variance Table

Response: Chl.prop
               Df   Sum Sq  Mean Sq F value    Pr(>F)    
Site            1 0.001563 0.001563  0.5375  0.466633    
Genotype        2 0.297307 0.148654 51.1117 3.495e-13 ***
TimeP           2 0.132285 0.066142 22.7418 6.845e-08 ***
Site:Genotype   2 0.041114 0.020557  7.0681  0.001877 ** 
Site:TimeP      2 0.038643 0.019322  6.6434  0.002634 ** 
Genotype:TimeP  4 0.218951 0.054738 18.8205 9.691e-10 ***
Residuals      54 0.157054 0.002908                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Chl_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter      |     Eta2 |       95% CI
----------------------------------------
Site           | 1.76e-03 | [0.00, 1.00]
Genotype       |     0.34 | [0.16, 1.00]
TimeP          |     0.15 | [0.02, 1.00]
Site:Genotype  |     0.05 | [0.00, 1.00]
Site:TimeP     |     0.04 | [0.00, 1.00]
Genotype:TimeP |     0.25 | [0.06, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Chl_lm.res<-data.frame(anova(Tol_Chl_lm))
Tol_Chl_lm.res$Predictor<-rownames(Tol_Chl_lm.res)
Tol_Chl_lm.res$EtaSq<-c(eta_squared(Tol_Chl_lm, partial=FALSE)$Eta2, NA)
Tol_Chl_lm.res$Response<-rep("Chlorophyll", nrow(Tol_Chl_lm.res))
Tol_Chl_lm.res<-Tol_Chl_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Strong influence of Timepoint, including interactions with main variables of interest, Site and Genotype. Will analyze each Timepoint individually.

Chl Summer 1 Timepoint W2

Run Model

##Check normality
hist(TolData_W2$Chl.prop)

shapiro.test(TolData_W2$Chl.prop)

    Shapiro-Wilk normality test

data:  TolData_W2$Chl.prop
W = 0.98407, p-value = 0.9671
#Normal

##Model as a function of Site and Genotype
Tol_Chl_W2_lm<-lm(Chl.prop~Site+Genotype+Site:Genotype, data=TolData_W2)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Chl_W2_lm)))


#Q-Q plot
qqnorm(resid(Tol_Chl_W2_lm)); qqline(resid(Tol_Chl_W2_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Chl_W2_lm), resid(Tol_Chl_W2_lm))

Model Results

Overall

#Model Results
summary(Tol_Chl_W2_lm)

Call:
lm(formula = Chl.prop ~ Site + Genotype + Site:Genotype, data = TolData_W2)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.089900 -0.031587 -0.008183  0.038881  0.103550 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.1842264  0.0119450  15.423 5.03e-11 ***
Site.L             0.0188110  0.0168928   1.114 0.281921    
Genotype.L        -0.0947759  0.0204291  -4.639 0.000273 ***
Genotype.Q        -0.0585870  0.0209464  -2.797 0.012921 *  
Site.L:Genotype.L -0.0002833  0.0288911  -0.010 0.992297    
Site.L:Genotype.Q  0.0366569  0.0296227   1.237 0.233769    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.05552 on 16 degrees of freedom
  (1 observation deleted due to missingness)
Multiple R-squared:  0.6758,    Adjusted R-squared:  0.5745 
F-statistic: 6.671 on 5 and 16 DF,  p-value: 0.001551
anova(Tol_Chl_W2_lm)
Analysis of Variance Table

Response: Chl.prop
              Df   Sum Sq  Mean Sq F value   Pr(>F)    
Site           1 0.005580 0.005580  1.8106 0.197195    
Genotype       2 0.092482 0.046241 15.0038 0.000214 ***
Site:Genotype  2 0.004732 0.002366  0.7677 0.480448    
Residuals     16 0.049311 0.003082                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Chl_W2_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     | Eta2 |       95% CI
-----------------------------------
Site          | 0.04 | [0.00, 1.00]
Genotype      | 0.61 | [0.29, 1.00]
Site:Genotype | 0.03 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Chl_W2_lm.res<-data.frame(anova(Tol_Chl_W2_lm))
Tol_Chl_W2_lm.res$Predictor<-rownames(Tol_Chl_W2_lm.res)
Tol_Chl_W2_lm.res$EtaSq<-c(eta_squared(Tol_Chl_W2_lm, partial=FALSE)$Eta2, NA)
Tol_Chl_W2_lm.res$Response<-rep("Chlorophyll", nrow(Tol_Chl_W2_lm.res))
Tol_Chl_W2_lm.res$TimeP<-rep("W2", nrow(Tol_Chl_W2_lm.res))
Tol_Chl_W2_lm.res<-Tol_Chl_W2_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_Chl_W2_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10     0.2033 0.0278 16   0.1445    0.262
 AC12     0.2399 0.0278 16   0.1811    0.299
 AC8      0.0696 0.0278 16   0.0107    0.128

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10     0.2514 0.0278 16   0.1925    0.310
 AC12     0.2242 0.0321 16   0.1563    0.292
 AC8      0.1170 0.0321 16   0.0491    0.185

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12  -0.0366 0.0393 16  -0.933  0.6280
 AC10 - AC8    0.1338 0.0393 16   3.407  0.0095
 AC12 - AC8    0.1704 0.0393 16   4.340  0.0014

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0272 0.0424 16   0.640  0.8003
 AC10 - AC8    0.1343 0.0424 16   3.168  0.0156
 AC12 - AC8    0.1072 0.0453 16   2.364  0.0753

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_Chl_W2_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL   0.2033 0.0278 16   0.1445    0.262
 SS   0.2514 0.0278 16   0.1925    0.310

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL   0.2399 0.0278 16   0.1811    0.299
 SS   0.2242 0.0321 16   0.1563    0.292

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL   0.0696 0.0278 16   0.0107    0.128
 SS   0.1170 0.0321 16   0.0491    0.185

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0481 0.0393 16  -1.224  0.2387

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS    0.0157 0.0424 16   0.371  0.7156

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0475 0.0424 16  -1.120  0.2793
##Save p-values

#Genotypes within Sites
Tol_Chl_W2_lm.geno<-data.frame(emmeans(Tol_Chl_W2_lm, pairwise~Genotype | Site)$contrasts)
Tol_Chl_W2_lm.geno<-Tol_Chl_W2_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Chl_W2_lm.geno$group1<-paste(Tol_Chl_W2_lm.geno$Site, Tol_Chl_W2_lm.geno$group1, sep="_")
Tol_Chl_W2_lm.geno$group2<-paste(Tol_Chl_W2_lm.geno$Site, Tol_Chl_W2_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_Chl_W2_lm.site<-data.frame(emmeans(Tol_Chl_W2_lm, pairwise~Site | Genotype)$contrasts)
Tol_Chl_W2_lm.site<-Tol_Chl_W2_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Chl_W2_lm.site$group1<-paste(Tol_Chl_W2_lm.site$group1, Tol_Chl_W2_lm.site$Genotype, sep="_")
Tol_Chl_W2_lm.site$group2<-paste(Tol_Chl_W2_lm.site$group2, Tol_Chl_W2_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_Chl_W2_lm.p<-rbind(Tol_Chl_W2_lm.geno[,c(1:2,4:8)], Tol_Chl_W2_lm.site[,c(1:2,4:8)])
Tol_Chl_W2_lm.p<-Tol_Chl_W2_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_Chl_W2_lm.p$Sig<-ifelse(Tol_Chl_W2_lm.p$p<0.001, "***", ifelse(Tol_Chl_W2_lm.p$p<0.01, "**", ifelse(Tol_Chl_W2_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_Chl_W2_lm.p$Response<-rep("Chlorophyll", nrow(Tol_Chl_W2_lm.p))
Tol_Chl_W2_lm.p$TimeP<-rep("W2", nrow(Tol_Chl_W2_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_Chl_W2_SG<-summarySE(TolData_W2, measurevar="Chl.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_Chl_W2_SG.plot<-ggplot(Tol_Chl_W2_SG, aes(x=Site.Geno, y=Chl.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Chl.prop-se, ymax=Chl.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Chlorophyll Retention")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
  ylim(0, 1)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Chl_W2_lm.p,  y.position=0.4, step.increase=0.25, label="Sig", hide.ns=TRUE); Tol_Chl_W2_SG.plot

Chl Summer 2 Timepoint M1

Run Model

##Check normality
hist(TolData_M1$Chl.prop)

shapiro.test(TolData_M1$Chl.prop)

    Shapiro-Wilk normality test

data:  TolData_M1$Chl.prop
W = 0.9306, p-value = 0.1263
#Normal

##Model as a function of Site and Genotype
Tol_Chl_M1_lm<-lm(Chl.prop~Site+Genotype+Site:Genotype, data=TolData_M1)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Chl_M1_lm)))


#Q-Q plot
qqnorm(resid(Tol_Chl_M1_lm)); qqline(resid(Tol_Chl_M1_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Chl_M1_lm), resid(Tol_Chl_M1_lm))

Model Results

Overall

#Model Results
summary(Tol_Chl_M1_lm)

Call:
lm(formula = Chl.prop ~ Site + Genotype + Site:Genotype, data = TolData_M1)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.107050 -0.034575  0.003479  0.025531  0.088050 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.17217    0.01178  14.619 1.12e-10 ***
Site.L             0.01036    0.01666   0.622   0.5428    
Genotype.L        -0.16337    0.01935  -8.442 2.74e-07 ***
Genotype.Q         0.06169    0.02139   2.883   0.0108 *  
Site.L:Genotype.L  0.03819    0.02737   1.395   0.1820    
Site.L:Genotype.Q  0.05454    0.03026   1.803   0.0903 .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.05474 on 16 degrees of freedom
Multiple R-squared:  0.8424,    Adjusted R-squared:  0.7932 
F-statistic: 17.11 on 5 and 16 DF,  p-value: 6.411e-06
anova(Tol_Chl_M1_lm)
Analysis of Variance Table

Response: Chl.prop
              Df   Sum Sq  Mean Sq F value    Pr(>F)    
Site           1 0.002283 0.002283  0.7619    0.3956    
Genotype       2 0.238424 0.119212 39.7888 6.168e-07 ***
Site:Genotype  2 0.015569 0.007785  2.5982    0.1054    
Residuals     16 0.047938 0.002996                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Chl_M1_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     |     Eta2 |       95% CI
---------------------------------------
Site          | 7.50e-03 | [0.00, 1.00]
Genotype      |     0.78 | [0.58, 1.00]
Site:Genotype |     0.05 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Chl_M1_lm.res<-data.frame(anova(Tol_Chl_M1_lm))
Tol_Chl_M1_lm.res$Predictor<-rownames(Tol_Chl_M1_lm.res)
Tol_Chl_M1_lm.res$EtaSq<-c(eta_squared(Tol_Chl_M1_lm, partial=FALSE)$Eta2, NA)
Tol_Chl_M1_lm.res$Response<-rep("Chlorophyll", nrow(Tol_Chl_M1_lm.res))
Tol_Chl_M1_lm.res$TimeP<-rep("M1", nrow(Tol_Chl_M1_lm.res))
Tol_Chl_M1_lm.res<-Tol_Chl_M1_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_Chl_M1_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10     0.3089 0.0274 16   0.2509   0.3669
 AC12     0.1460 0.0316 16   0.0790   0.2130
 AC8      0.0397 0.0274 16  -0.0183   0.0977

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10     0.3169 0.0274 16   0.2588   0.3749
 AC12     0.0976 0.0316 16   0.0306   0.1646
 AC8      0.1240 0.0274 16   0.0660   0.1820

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.1629 0.0418 16   3.897  0.0035
 AC10 - AC8    0.2692 0.0387 16   6.956  <.0001
 AC12 - AC8    0.1063 0.0418 16   2.543  0.0538

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.2192 0.0418 16   5.244  0.0002
 AC10 - AC8    0.1928 0.0387 16   4.983  0.0004
 AC12 - AC8   -0.0264 0.0418 16  -0.631  0.8056

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_Chl_M1_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL   0.3089 0.0274 16   0.2509   0.3669
 SS   0.3169 0.0274 16   0.2588   0.3749

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL   0.1460 0.0316 16   0.0790   0.2130
 SS   0.0976 0.0316 16   0.0306   0.1646

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL   0.0397 0.0274 16  -0.0183   0.0977
 SS   0.1240 0.0274 16   0.0660   0.1820

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS  -0.00795 0.0387 16  -0.205  0.8398

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS   0.04833 0.0447 16   1.081  0.2955

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS  -0.08432 0.0387 16  -2.179  0.0447
##Save p-values

#Genotypes within Sites
Tol_Chl_M1_lm.geno<-data.frame(emmeans(Tol_Chl_M1_lm, pairwise~Genotype | Site)$contrasts)
Tol_Chl_M1_lm.geno<-Tol_Chl_M1_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Chl_M1_lm.geno$group1<-paste(Tol_Chl_M1_lm.geno$Site, Tol_Chl_M1_lm.geno$group1, sep="_")
Tol_Chl_M1_lm.geno$group2<-paste(Tol_Chl_M1_lm.geno$Site, Tol_Chl_M1_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_Chl_M1_lm.site<-data.frame(emmeans(Tol_Chl_M1_lm, pairwise~Site | Genotype)$contrasts)
Tol_Chl_M1_lm.site<-Tol_Chl_M1_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Chl_M1_lm.site$group1<-paste(Tol_Chl_M1_lm.site$group1, Tol_Chl_M1_lm.site$Genotype, sep="_")
Tol_Chl_M1_lm.site$group2<-paste(Tol_Chl_M1_lm.site$group2, Tol_Chl_M1_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_Chl_M1_lm.p<-rbind(Tol_Chl_M1_lm.geno[,c(1:2,4:8)], Tol_Chl_M1_lm.site[,c(1:2,4:8)])
Tol_Chl_M1_lm.p<-Tol_Chl_M1_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_Chl_M1_lm.p$Sig<-ifelse(Tol_Chl_M1_lm.p$p<0.001, "***", ifelse(Tol_Chl_M1_lm.p$p<0.01, "**", ifelse(Tol_Chl_M1_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_Chl_M1_lm.p$Response<-rep("Chlorophyll", nrow(Tol_Chl_M1_lm.p))
Tol_Chl_M1_lm.p$TimeP<-rep("M1", nrow(Tol_Chl_M1_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_Chl_M1_SG<-summarySE(TolData_M1, measurevar="Chl.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_Chl_M1_SG.plot<-ggplot(Tol_Chl_M1_SG, aes(x=Site.Geno, y=Chl.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Chl.prop-se, ymax=Chl.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Chlorophyll Retention")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
  ylim(0, 1)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Chl_M1_lm.p,  y.position=0.4, step.increase=0.25, label="Sig", hide.ns=TRUE); Tol_Chl_M1_SG.plot

Chl Winter Timepoint M4

Run Model

##Check normality
hist(TolData_M4$Chl.prop)

shapiro.test(TolData_M4$Chl.prop)

    Shapiro-Wilk normality test

data:  TolData_M4$Chl.prop
W = 0.91299, p-value = 0.04096
#Not Normal

##Try log+1 transformation
hist(log(TolData_M4$Chl.prop+1))

shapiro.test(log(TolData_M4$Chl.prop+1))

    Shapiro-Wilk normality test

data:  log(TolData_M4$Chl.prop + 1)
W = 0.93102, p-value = 0.1028
#Normal

##Model as a function of Site and Genotype
##Model with log transformation
Tol_Chl_M4_lm<-lm(log(Chl.prop+1)~Site+Genotype+Site:Genotype, data=TolData_M4)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Chl_M4_lm)))


#Q-Q plot
qqnorm(resid(Tol_Chl_M4_lm)); qqline(resid(Tol_Chl_M4_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Chl_M4_lm), resid(Tol_Chl_M4_lm))

Model Results

Overall

#Model Results
summary(Tol_Chl_M4_lm)

Call:
lm(formula = log(Chl.prop + 1) ~ Site + Genotype + Site:Genotype, 
    data = TolData_M4)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.062753 -0.025900 -0.004896  0.017009  0.065759 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.23863    0.00807  29.568  < 2e-16 ***
Site.L            -0.04272    0.01141  -3.743  0.00149 ** 
Genotype.L        -0.03027    0.01398  -2.166  0.04400 *  
Genotype.Q        -0.11052    0.01398  -7.907  2.9e-07 ***
Site.L:Genotype.L -0.03189    0.01977  -1.613  0.12415    
Site.L:Genotype.Q  0.05753    0.01977   2.910  0.00934 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.03954 on 18 degrees of freedom
Multiple R-squared:  0.8368,    Adjusted R-squared:  0.7915 
F-statistic: 18.46 on 5 and 18 DF,  p-value: 1.598e-06
anova(Tol_Chl_M4_lm)
Analysis of Variance Table

Response: log(Chl.prop + 1)
              Df   Sum Sq  Mean Sq F value    Pr(>F)    
Site           1 0.021901 0.021901 14.0102  0.001489 ** 
Genotype       2 0.105056 0.052528 33.6031 8.379e-07 ***
Site:Genotype  2 0.017304 0.008652  5.5349  0.013381 *  
Residuals     18 0.028137 0.001563                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Chl_M4_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     | Eta2 |       95% CI
-----------------------------------
Site          | 0.13 | [0.00, 1.00]
Genotype      | 0.61 | [0.32, 1.00]
Site:Genotype | 0.10 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Chl_M4_lm.res<-data.frame(anova(Tol_Chl_M4_lm))
Tol_Chl_M4_lm.res$Predictor<-rownames(Tol_Chl_M4_lm.res)
Tol_Chl_M4_lm.res$EtaSq<-c(eta_squared(Tol_Chl_M4_lm, partial=FALSE)$Eta2, NA)
Tol_Chl_M4_lm.res$Response<-rep("Chlorophyll", nrow(Tol_Chl_M4_lm.res))
Tol_Chl_M4_lm.res$TimeP<-rep("M4", nrow(Tol_Chl_M4_lm.res))
Tol_Chl_M4_lm.res<-Tol_Chl_M4_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Site and Genotype and Site*Genotype.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_Chl_M4_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.213 0.0198 18    0.171    0.254
 AC12      0.392 0.0198 18    0.351    0.434
 AC8       0.202 0.0198 18    0.160    0.243

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.217 0.0198 18    0.176    0.259
 AC12      0.265 0.0198 18    0.224    0.307
 AC8       0.143 0.0198 18    0.101    0.184

Results are given on the log(mu + 1) (not the response) scale. 
Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate    SE df t.ratio p.value
 AC10 - AC12  -0.1797 0.028 18  -6.428  <.0001
 AC10 - AC8    0.0109 0.028 18   0.391  0.9196
 AC12 - AC8    0.1906 0.028 18   6.819  <.0001

Site = SS:
 contrast    estimate    SE df t.ratio p.value
 AC10 - AC12  -0.0482 0.028 18  -1.724  0.2237
 AC10 - AC8    0.0747 0.028 18   2.672  0.0393
 AC12 - AC8    0.1229 0.028 18   4.396  0.0010

Note: contrasts are still on the log(mu + 1) scale 
P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_Chl_M4_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.213 0.0198 18    0.171    0.254
 SS    0.217 0.0198 18    0.176    0.259

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    0.392 0.0198 18    0.351    0.434
 SS    0.265 0.0198 18    0.224    0.307

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.202 0.0198 18    0.160    0.243
 SS    0.143 0.0198 18    0.101    0.184

Results are given on the log(mu + 1) (not the response) scale. 
Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate    SE df t.ratio p.value
 KL - SS  -0.00468 0.028 18  -0.167  0.8688

Genotype = AC12:
 contrast estimate    SE df t.ratio p.value
 KL - SS   0.12684 0.028 18   4.537  0.0003

Genotype = AC8:
 contrast estimate    SE df t.ratio p.value
 KL - SS   0.05909 0.028 18   2.114  0.0488

Note: contrasts are still on the log(mu + 1) scale 
##Save p-values

#Genotypes within Sites
Tol_Chl_M4_lm.geno<-data.frame(emmeans(Tol_Chl_M4_lm, pairwise~Genotype | Site)$contrasts)
Tol_Chl_M4_lm.geno<-Tol_Chl_M4_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Chl_M4_lm.geno$group1<-paste(Tol_Chl_M4_lm.geno$Site, Tol_Chl_M4_lm.geno$group1, sep="_")
Tol_Chl_M4_lm.geno$group2<-paste(Tol_Chl_M4_lm.geno$Site, Tol_Chl_M4_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_Chl_M4_lm.site<-data.frame(emmeans(Tol_Chl_M4_lm, pairwise~Site | Genotype)$contrasts)
Tol_Chl_M4_lm.site<-Tol_Chl_M4_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Chl_M4_lm.site$group1<-paste(Tol_Chl_M4_lm.site$group1, Tol_Chl_M4_lm.site$Genotype, sep="_")
Tol_Chl_M4_lm.site$group2<-paste(Tol_Chl_M4_lm.site$group2, Tol_Chl_M4_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_Chl_M4_lm.p<-rbind(Tol_Chl_M4_lm.geno[,c(1:2,4:8)], Tol_Chl_M4_lm.site[,c(1:2,4:8)])
Tol_Chl_M4_lm.p<-Tol_Chl_M4_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_Chl_M4_lm.p$Sig<-ifelse(Tol_Chl_M4_lm.p$p<0.001, "***", ifelse(Tol_Chl_M4_lm.p$p<0.01, "**", ifelse(Tol_Chl_M4_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_Chl_M4_lm.p$Response<-rep("Chlorophyll", nrow(Tol_Chl_M4_lm.p))
Tol_Chl_M4_lm.p$TimeP<-rep("M4", nrow(Tol_Chl_M4_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_Chl_M4_SG<-summarySE(TolData_M4, measurevar="Chl.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_Chl_M4_SG.plot<-ggplot(Tol_Chl_M4_SG, aes(x=Site.Geno, y=Chl.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Chl.prop-se, ymax=Chl.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Chlorophyll Retention")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
  ylim(0, 1)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Chl_M4_lm.p,  y.position=0.55, step.increase=0.20, label="Sig", hide.ns=TRUE); Tol_Chl_M4_SG.plot

Thermal Tolerance Symbionts

Full Set

Run Model

##Check normality
hist(TolData$Sym.prop)

shapiro.test(TolData$Sym.prop)

    Shapiro-Wilk normality test

data:  TolData$Sym.prop
W = 0.92235, p-value = 0.0003707
#Not Normal

##Try log+1 transformation
hist(log(TolData$Sym.prop+1))

shapiro.test(log(TolData$Sym.prop+1))

    Shapiro-Wilk normality test

data:  log(TolData$Sym.prop + 1)
W = 0.92164, p-value = 0.000345
#Not normal 

##Try square transformation
hist((TolData$Sym.prop)^2)

shapiro.test((TolData$Sym.prop)^2)

    Shapiro-Wilk normality test

data:  (TolData$Sym.prop)^2
W = 0.87147, p-value = 3.933e-06
#Not normal 

##Try cubed transformation
hist((TolData$Sym.prop)^3)

shapiro.test((TolData$Sym.prop)^3)

    Shapiro-Wilk normality test

data:  (TolData$Sym.prop)^3
W = 0.80697, p-value = 4.342e-08
#Not normal 


##Model as a function of Site and Genotype and Timepoint
##Model with no transformation and check residuals
Tol_Sym_lm<-lm(Sym.prop~Site+Genotype+TimeP+ Site:Genotype + Site:TimeP + Genotype:TimeP, data=TolData)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Sym_lm)))


#Q-Q plot
qqnorm(resid(Tol_Sym_lm)); qqline(resid(Tol_Sym_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Sym_lm), resid(Tol_Sym_lm))

Model Results

#Model Results
summary(Tol_Sym_lm)

Call:
lm(formula = Sym.prop ~ Site + Genotype + TimeP + Site:Genotype + 
    Site:TimeP + Genotype:TimeP, data = TolData)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.37464 -0.08630 -0.00192  0.08972  0.35883 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)         0.544513   0.018576  29.313  < 2e-16 ***
Site.L             -0.001834   0.026197  -0.070 0.944443    
Genotype.L         -0.373179   0.031737 -11.758  < 2e-16 ***
Genotype.Q          0.028101   0.032605   0.862 0.392497    
TimeP.L             0.133503   0.031737   4.206 9.64e-05 ***
TimeP.Q             0.190344   0.032605   5.838 2.94e-07 ***
Site.L:Genotype.L  -0.060389   0.044883  -1.345 0.183999    
Site.L:Genotype.Q   0.074992   0.045930   1.633 0.108240    
Site.L:TimeP.L     -0.159707   0.044883  -3.558 0.000778 ***
Site.L:TimeP.Q     -0.027928   0.045930  -0.608 0.545653    
Genotype.L:TimeP.L  0.085371   0.055316   1.543 0.128489    
Genotype.Q:TimeP.L -0.084924   0.054623  -1.555 0.125749    
Genotype.L:TimeP.Q  0.065986   0.054623   1.208 0.232204    
Genotype.Q:TimeP.Q -0.205029   0.058264  -3.519 0.000878 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.1535 on 55 degrees of freedom
Multiple R-squared:  0.8036,    Adjusted R-squared:  0.7572 
F-statistic: 17.31 on 13 and 55 DF,  p-value: 6.022e-15
anova(Tol_Sym_lm)
Analysis of Variance Table

Response: Sym.prop
               Df Sum Sq Mean Sq F value    Pr(>F)    
Site            1 0.0007 0.00068  0.0289  0.865708    
Genotype        2 3.2796 1.63981 69.5880 8.602e-16 ***
TimeP           2 1.1556 0.57780 24.5197 2.438e-08 ***
Site:Genotype   2 0.1111 0.05557  2.3581  0.104096    
Site:TimeP      2 0.3138 0.15688  6.6576  0.002575 ** 
Genotype:TimeP  4 0.4428 0.11069  4.6974  0.002474 ** 
Residuals      55 1.2961 0.02356                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Sym_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter      |     Eta2 |       95% CI
----------------------------------------
Site           | 1.03e-04 | [0.00, 1.00]
Genotype       |     0.50 | [0.33, 1.00]
TimeP          |     0.18 | [0.04, 1.00]
Site:Genotype  |     0.02 | [0.00, 1.00]
Site:TimeP     |     0.05 | [0.00, 1.00]
Genotype:TimeP |     0.07 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Sym_lm.res<-data.frame(anova(Tol_Sym_lm))
Tol_Sym_lm.res$Predictor<-rownames(Tol_Sym_lm.res)
Tol_Sym_lm.res$EtaSq<-c(eta_squared(Tol_Sym_lm, partial=FALSE)$Eta2, NA)
Tol_Sym_lm.res$Response<-rep("Symbionts", nrow(Tol_Sym_lm.res))
Tol_Sym_lm.res<-Tol_Sym_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Strong influence of Timepoint, including interactions with main variables of interest, Site and Genotype. Will analyze each Timepoint individually.

Sym Summer 1 Timepoint W2

Run Model

##Check normality
hist(TolData_W2$Sym.prop)

shapiro.test(TolData_W2$Sym.prop)

    Shapiro-Wilk normality test

data:  TolData_W2$Sym.prop
W = 0.93605, p-value = 0.1477
#Normal

##Model as a function of Site and Genotype
Tol_Sym_W2_lm<-lm(Sym.prop~Site+Genotype+Site:Genotype, data=TolData_W2)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Sym_W2_lm)))


#Q-Q plot
qqnorm(resid(Tol_Sym_W2_lm)); qqline(resid(Tol_Sym_W2_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Sym_W2_lm), resid(Tol_Sym_W2_lm))

Model Results

Overall

#Model Results
summary(Tol_Sym_W2_lm)

Call:
lm(formula = Sym.prop ~ Site + Genotype + Site:Genotype, data = TolData_W2)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.26060 -0.11145  0.00000  0.08525  0.28580 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.5237625  0.0325072  16.112 9.90e-12 ***
Site.L             0.0939568  0.0459722   2.044   0.0568 .  
Genotype.L        -0.4152131  0.0570402  -7.279 1.29e-06 ***
Genotype.Q        -0.0005205  0.0555584  -0.009   0.9926    
Site.L:Genotype.L -0.2061000  0.0806671  -2.555   0.0205 *  
Site.L:Genotype.Q  0.0462891  0.0785715   0.589   0.5635    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.155 on 17 degrees of freedom
Multiple R-squared:  0.7924,    Adjusted R-squared:  0.7313 
F-statistic: 12.98 on 5 and 17 DF,  p-value: 2.647e-05
anova(Tol_Sym_W2_lm)
Analysis of Variance Table

Response: Sym.prop
              Df  Sum Sq Mean Sq F value    Pr(>F)    
Site           1 0.16148 0.16148  6.7208   0.01897 *  
Genotype       2 1.22843 0.61421 25.5640 7.508e-06 ***
Site:Genotype  2 0.16883 0.08441  3.5133   0.05283 .  
Residuals     17 0.40845 0.02403                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Sym_W2_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     | Eta2 |       95% CI
-----------------------------------
Site          | 0.08 | [0.00, 1.00]
Genotype      | 0.62 | [0.33, 1.00]
Site:Genotype | 0.09 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Sym_W2_lm.res<-data.frame(anova(Tol_Sym_W2_lm))
Tol_Sym_W2_lm.res$Predictor<-rownames(Tol_Sym_W2_lm.res)
Tol_Sym_W2_lm.res$EtaSq<-c(eta_squared(Tol_Sym_W2_lm, partial=FALSE)$Eta2, NA)
Tol_Sym_W2_lm.res$Response<-rep("Symbionts", nrow(Tol_Sym_W2_lm.res))
Tol_Sym_W2_lm.res$TimeP<-rep("W2", nrow(Tol_Sym_W2_lm.res))
Tol_Sym_W2_lm.res<-Tol_Sym_W2_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Site and Genotype. Marginal effect (p<0.1) of Site * Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_Sym_W2_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.634 0.0775 17   0.4708    0.798
 AC12      0.484 0.0775 17   0.3210    0.648
 AC8       0.253 0.0775 17   0.0897    0.417

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      1.000 0.0775 17   0.8365    1.164
 AC12      0.564 0.0775 17   0.4004    0.727
 AC8       0.207 0.0895 17   0.0179    0.396

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate    SE df t.ratio p.value
 AC10 - AC12    0.150 0.110 17   1.367  0.3795
 AC10 - AC8     0.381 0.110 17   3.477  0.0077
 AC12 - AC8     0.231 0.110 17   2.110  0.1174

Site = SS:
 contrast    estimate    SE df t.ratio p.value
 AC10 - AC12    0.436 0.110 17   3.979  0.0026
 AC10 - AC8     0.793 0.118 17   6.701  <.0001
 AC12 - AC8     0.357 0.118 17   3.017  0.0201

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_Sym_W2_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.634 0.0775 17   0.4708    0.798
 SS    1.000 0.0775 17   0.8365    1.164

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    0.484 0.0775 17   0.3210    0.648
 SS    0.564 0.0775 17   0.4004    0.727

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.253 0.0775 17   0.0897    0.417
 SS    0.207 0.0895 17   0.0179    0.396

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate    SE df t.ratio p.value
 KL - SS   -0.3657 0.110 17  -3.337  0.0039

Genotype = AC12:
 contrast estimate    SE df t.ratio p.value
 KL - SS   -0.0794 0.110 17  -0.725  0.4785

Genotype = AC8:
 contrast estimate    SE df t.ratio p.value
 KL - SS    0.0465 0.118 17   0.393  0.6994
##Save p-values

#Genotypes within Sites
Tol_Sym_W2_lm.geno<-data.frame(emmeans(Tol_Sym_W2_lm, pairwise~Genotype | Site)$contrasts)
Tol_Sym_W2_lm.geno<-Tol_Sym_W2_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Sym_W2_lm.geno$group1<-paste(Tol_Sym_W2_lm.geno$Site, Tol_Sym_W2_lm.geno$group1, sep="_")
Tol_Sym_W2_lm.geno$group2<-paste(Tol_Sym_W2_lm.geno$Site, Tol_Sym_W2_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_Sym_W2_lm.site<-data.frame(emmeans(Tol_Sym_W2_lm, pairwise~Site | Genotype)$contrasts)
Tol_Sym_W2_lm.site<-Tol_Sym_W2_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Sym_W2_lm.site$group1<-paste(Tol_Sym_W2_lm.site$group1, Tol_Sym_W2_lm.site$Genotype, sep="_")
Tol_Sym_W2_lm.site$group2<-paste(Tol_Sym_W2_lm.site$group2, Tol_Sym_W2_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_Sym_W2_lm.p<-rbind(Tol_Sym_W2_lm.geno[,c(1:2,4:8)], Tol_Sym_W2_lm.site[,c(1:2,4:8)])
Tol_Sym_W2_lm.p<-Tol_Sym_W2_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_Sym_W2_lm.p$Sig<-ifelse(Tol_Sym_W2_lm.p$p<0.001, "***", ifelse(Tol_Sym_W2_lm.p$p<0.01, "**", ifelse(Tol_Sym_W2_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_Sym_W2_lm.p$Response<-rep("Symbionts", nrow(Tol_Sym_W2_lm.p))
Tol_Sym_W2_lm.p$TimeP<-rep("W2", nrow(Tol_Sym_W2_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_Sym_W2_SG<-summarySE(TolData_W2, measurevar="Sym.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_Sym_W2_SG.plot<-ggplot(Tol_Sym_W2_SG, aes(x=Site.Geno, y=Sym.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Sym.prop-se, ymax=Sym.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Symbiont Retention")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
  ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Sym_W2_lm.p,  y.position=0.95, step.increase=0.15, label="Sig", hide.ns=TRUE); Tol_Sym_W2_SG.plot

Sym Summer 2 Timepoint M1

Run Model

##Check normality
hist(TolData_M1$Sym.prop)

shapiro.test(TolData_M1$Sym.prop)

    Shapiro-Wilk normality test

data:  TolData_M1$Sym.prop
W = 0.85748, p-value = 0.004618
#Not normal

##Try log+1 transformation
hist(log(TolData_M1$Sym.prop+1))

shapiro.test(log(TolData_M1$Sym.prop+1))

    Shapiro-Wilk normality test

data:  log(TolData_M1$Sym.prop + 1)
W = 0.87335, p-value = 0.009041
#Not normal but improved

##Model as a function of Site and Genotype
##Model with log transformation
Tol_Sym_M1_lm<-lm(log(Sym.prop+1)~Site+Genotype+Site:Genotype, data=TolData_M1)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Sym_M1_lm)))


#Q-Q plot
qqnorm(resid(Tol_Sym_M1_lm)); qqline(resid(Tol_Sym_M1_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Sym_M1_lm), resid(Tol_Sym_M1_lm))

Model Results

Overall

#Model Results
summary(Tol_Sym_M1_lm)

Call:
lm(formula = log(Sym.prop + 1) ~ Site + Genotype + Site:Genotype, 
    data = TolData_M1)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.098079 -0.055799 -0.004888  0.043331  0.151113 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.307716   0.016556  18.587 2.95e-12 ***
Site.L             0.027767   0.023413   1.186 0.252954    
Genotype.L        -0.295494   0.027204 -10.862 8.59e-09 ***
Genotype.Q         0.129387   0.030075   4.302 0.000548 ***
Site.L:Genotype.L  0.080682   0.038472   2.097 0.052224 .  
Site.L:Genotype.Q -0.005572   0.042532  -0.131 0.897412    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.07694 on 16 degrees of freedom
Multiple R-squared:  0.8989,    Adjusted R-squared:  0.8673 
F-statistic: 28.46 on 5 and 16 DF,  p-value: 2e-07
anova(Tol_Sym_M1_lm)
Analysis of Variance Table

Response: log(Sym.prop + 1)
              Df  Sum Sq Mean Sq F value    Pr(>F)    
Site           1 0.00823 0.00823  1.3902    0.2556    
Genotype       2 0.80811 0.40406 68.2486 1.468e-08 ***
Site:Genotype  2 0.02614 0.01307  2.2076    0.1423    
Residuals     16 0.09473 0.00592                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Sym_M1_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     |     Eta2 |       95% CI
---------------------------------------
Site          | 8.78e-03 | [0.00, 1.00]
Genotype      |     0.86 | [0.73, 1.00]
Site:Genotype |     0.03 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Sym_M1_lm.res<-data.frame(anova(Tol_Sym_M1_lm))
Tol_Sym_M1_lm.res$Predictor<-rownames(Tol_Sym_M1_lm.res)
Tol_Sym_M1_lm.res$EtaSq<-c(eta_squared(Tol_Sym_M1_lm, partial=FALSE)$Eta2, NA)
Tol_Sym_M1_lm.res$Response<-rep("Symbionts", nrow(Tol_Sym_M1_lm.res))
Tol_Sym_M1_lm.res$TimeP<-rep("M1", nrow(Tol_Sym_M1_lm.res))
Tol_Sym_M1_lm.res<-Tol_Sym_M1_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_Sym_M1_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10     0.5918 0.0385 16   0.5102    0.673
 AC12     0.1792 0.0444 16   0.0850    0.273
 AC8      0.0932 0.0385 16   0.0117    0.175

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10     0.5472 0.0385 16   0.4656    0.629
 AC12     0.2249 0.0444 16   0.1307    0.319
 AC8      0.2100 0.0385 16   0.1284    0.292

Results are given on the log(mu + 1) (not the response) scale. 
Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12    0.413 0.0588 16   7.021  <.0001
 AC10 - AC8     0.499 0.0544 16   9.164  <.0001
 AC12 - AC8     0.086 0.0588 16   1.463  0.3339

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12    0.322 0.0588 16   5.483  0.0001
 AC10 - AC8     0.337 0.0544 16   6.198  <.0001
 AC12 - AC8     0.015 0.0588 16   0.255  0.9650

Note: contrasts are still on the log(mu + 1) scale 
P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_Sym_M1_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL   0.5918 0.0385 16   0.5102    0.673
 SS   0.5472 0.0385 16   0.4656    0.629

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL   0.1792 0.0444 16   0.0850    0.273
 SS   0.2249 0.0444 16   0.1307    0.319

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL   0.0932 0.0385 16   0.0117    0.175
 SS   0.2100 0.0385 16   0.1284    0.292

Results are given on the log(mu + 1) (not the response) scale. 
Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS    0.0446 0.0544 16   0.820  0.4241

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0457 0.0628 16  -0.727  0.4775

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.1167 0.0544 16  -2.146  0.0476

Note: contrasts are still on the log(mu + 1) scale 
##Save p-values

#Genotypes within Sites
Tol_Sym_M1_lm.geno<-data.frame(emmeans(Tol_Sym_M1_lm, pairwise~Genotype | Site)$contrasts)
Tol_Sym_M1_lm.geno<-Tol_Sym_M1_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Sym_M1_lm.geno$group1<-paste(Tol_Sym_M1_lm.geno$Site, Tol_Sym_M1_lm.geno$group1, sep="_")
Tol_Sym_M1_lm.geno$group2<-paste(Tol_Sym_M1_lm.geno$Site, Tol_Sym_M1_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_Sym_M1_lm.site<-data.frame(emmeans(Tol_Sym_M1_lm, pairwise~Site | Genotype)$contrasts)
Tol_Sym_M1_lm.site<-Tol_Sym_M1_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Sym_M1_lm.site$group1<-paste(Tol_Sym_M1_lm.site$group1, Tol_Sym_M1_lm.site$Genotype, sep="_")
Tol_Sym_M1_lm.site$group2<-paste(Tol_Sym_M1_lm.site$group2, Tol_Sym_M1_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_Sym_M1_lm.p<-rbind(Tol_Sym_M1_lm.geno[,c(1:2,4:8)], Tol_Sym_M1_lm.site[,c(1:2,4:8)])
Tol_Sym_M1_lm.p<-Tol_Sym_M1_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_Sym_M1_lm.p$Sig<-ifelse(Tol_Sym_M1_lm.p$p<0.001, "***", ifelse(Tol_Sym_M1_lm.p$p<0.01, "**", ifelse(Tol_Sym_M1_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_Sym_M1_lm.p$Response<-rep("Symbionts", nrow(Tol_Sym_M1_lm.p))
Tol_Sym_M1_lm.p$TimeP<-rep("M1", nrow(Tol_Sym_M1_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_Sym_M1_SG<-summarySE(TolData_M1, measurevar="Sym.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_Sym_M1_SG.plot<-ggplot(Tol_Sym_M1_SG, aes(x=Site.Geno, y=Sym.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Sym.prop-se, ymax=Sym.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Symbiont Retention")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
 ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Sym_M1_lm.p,  y.position=0.95, step.increase=0.15, label="Sig", hide.ns=TRUE); Tol_Sym_M1_SG.plot

Sym Winter Timepoint M4

Run Model

##Check normality
hist(TolData_M4$Sym.prop)

shapiro.test(TolData_M4$Sym.prop)

    Shapiro-Wilk normality test

data:  TolData_M4$Sym.prop
W = 0.88557, p-value = 0.01078
#Not Normal

##Try square transformation
hist((TolData_M4$Sym.prop)^2)

shapiro.test((TolData_M4$Sym.prop)^2)

    Shapiro-Wilk normality test

data:  (TolData_M4$Sym.prop)^2
W = 0.87973, p-value = 0.008208
#Not Normal

##Try cubed transformation
hist((TolData_M4$Sym.prop)^3)

shapiro.test((TolData_M4$Sym.prop)^3)

    Shapiro-Wilk normality test

data:  (TolData_M4$Sym.prop)^3
W = 0.8488, p-value = 0.002077
#Not Normal

##Model as a function of Site and Genotype
##Model with no transformation and check residuals
Tol_Sym_M4_lm<-lm(Sym.prop~Site+Genotype+Site:Genotype, data=TolData_M4)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Sym_M4_lm)))


#Q-Q plot
qqnorm(resid(Tol_Sym_M4_lm)); qqline(resid(Tol_Sym_M4_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Sym_M4_lm), resid(Tol_Sym_M4_lm))

Model Results

Overall

#Model Results
summary(Tol_Sym_M4_lm)

Call:
lm(formula = Sym.prop ~ Site + Genotype + Site:Genotype, data = TolData_M4)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.31820 -0.08804  0.00000  0.08618  0.29740 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.71662    0.03157  22.702 1.07e-14 ***
Site.L            -0.12617    0.04464  -2.826   0.0112 *  
Genotype.L        -0.28587    0.05467  -5.229 5.67e-05 ***
Genotype.Q        -0.11565    0.05467  -2.115   0.0486 *  
Site.L:Genotype.L -0.09494    0.07732  -1.228   0.2353    
Site.L:Genotype.Q  0.17275    0.07732   2.234   0.0384 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.1546 on 18 degrees of freedom
Multiple R-squared:  0.7201,    Adjusted R-squared:  0.6423 
F-statistic:  9.26 on 5 and 18 DF,  p-value: 0.0001686
anova(Tol_Sym_M4_lm)
Analysis of Variance Table

Response: Sym.prop
              Df  Sum Sq Mean Sq F value   Pr(>F)    
Site           1 0.19101 0.19101  7.9874 0.011190 *  
Genotype       2 0.76080 0.38040 15.9068 0.000105 ***
Site:Genotype  2 0.15542 0.07771  3.2496 0.062386 .  
Residuals     18 0.43046 0.02391                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Sym_M4_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     | Eta2 |       95% CI
-----------------------------------
Site          | 0.12 | [0.00, 1.00]
Genotype      | 0.49 | [0.18, 1.00]
Site:Genotype | 0.10 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Sym_M4_lm.res<-data.frame(anova(Tol_Sym_M4_lm))
Tol_Sym_M4_lm.res$Predictor<-rownames(Tol_Sym_M4_lm.res)
Tol_Sym_M4_lm.res$EtaSq<-c(eta_squared(Tol_Sym_M4_lm, partial=FALSE)$Eta2, NA)
Tol_Sym_M4_lm.res$Response<-rep("Symbionts", nrow(Tol_Sym_M4_lm.res))
Tol_Sym_M4_lm.res$TimeP<-rep("M4", nrow(Tol_Sym_M4_lm.res))
Tol_Sym_M4_lm.res<-Tol_Sym_M4_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Site and Genotype. Marginal effect (p<0.1) of Site * Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_Sym_M4_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.863 0.0773 18    0.701    1.026
 AC12      1.000 0.0773 18    0.838    1.162
 AC8       0.554 0.0773 18    0.392    0.717

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.880 0.0773 18    0.717    1.042
 AC12      0.622 0.0773 18    0.460    0.785
 AC8       0.380 0.0773 18    0.218    0.543

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate    SE df t.ratio p.value
 AC10 - AC12   -0.137 0.109 18  -1.249  0.4409
 AC10 - AC8     0.309 0.109 18   2.829  0.0285
 AC12 - AC8     0.446 0.109 18   4.078  0.0019

Site = SS:
 contrast    estimate    SE df t.ratio p.value
 AC10 - AC12    0.258 0.109 18   2.356  0.0734
 AC10 - AC8     0.499 0.109 18   4.565  0.0007
 AC12 - AC8     0.242 0.109 18   2.210  0.0965

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_Sym_M4_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.863 0.0773 18    0.701    1.026
 SS    0.880 0.0773 18    0.717    1.042

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    1.000 0.0773 18    0.838    1.162
 SS    0.622 0.0773 18    0.460    0.785

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.554 0.0773 18    0.392    0.717
 SS    0.380 0.0773 18    0.218    0.543

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate    SE df t.ratio p.value
 KL - SS   -0.0163 0.109 18  -0.149  0.8835

Genotype = AC12:
 contrast estimate    SE df t.ratio p.value
 KL - SS    0.3779 0.109 18   3.456  0.0028

Genotype = AC8:
 contrast estimate    SE df t.ratio p.value
 KL - SS    0.1736 0.109 18   1.588  0.1297
##Save p-values

#Genotypes within Sites
Tol_Sym_M4_lm.geno<-data.frame(emmeans(Tol_Sym_M4_lm, pairwise~Genotype | Site)$contrasts)
Tol_Sym_M4_lm.geno<-Tol_Sym_M4_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Sym_M4_lm.geno$group1<-paste(Tol_Sym_M4_lm.geno$Site, Tol_Sym_M4_lm.geno$group1, sep="_")
Tol_Sym_M4_lm.geno$group2<-paste(Tol_Sym_M4_lm.geno$Site, Tol_Sym_M4_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_Sym_M4_lm.site<-data.frame(emmeans(Tol_Sym_M4_lm, pairwise~Site | Genotype)$contrasts)
Tol_Sym_M4_lm.site<-Tol_Sym_M4_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Sym_M4_lm.site$group1<-paste(Tol_Sym_M4_lm.site$group1, Tol_Sym_M4_lm.site$Genotype, sep="_")
Tol_Sym_M4_lm.site$group2<-paste(Tol_Sym_M4_lm.site$group2, Tol_Sym_M4_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_Sym_M4_lm.p<-rbind(Tol_Sym_M4_lm.geno[,c(1:2,4:8)], Tol_Sym_M4_lm.site[,c(1:2,4:8)])
Tol_Sym_M4_lm.p<-Tol_Sym_M4_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_Sym_M4_lm.p$Sig<-ifelse(Tol_Sym_M4_lm.p$p<0.001, "***", ifelse(Tol_Sym_M4_lm.p$p<0.01, "**", ifelse(Tol_Sym_M4_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_Sym_M4_lm.p$Response<-rep("Symbionts", nrow(Tol_Sym_M4_lm.p))
Tol_Sym_M4_lm.p$TimeP<-rep("M4", nrow(Tol_Sym_M4_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_Sym_M4_SG<-summarySE(TolData_M4, measurevar="Sym.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_Sym_M4_SG.plot<-ggplot(Tol_Sym_M4_SG, aes(x=Site.Geno, y=Sym.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Sym.prop-se, ymax=Sym.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Symbiont Retention")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
  ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Sym_M4_lm.p,  y.position=1.1, step.increase=0.15, label="Sig", hide.ns=TRUE); Tol_Sym_M4_SG.plot

Thermal Tolerance Color Full Set

Full Set

Run Model

##Check normality
hist(TolData$Score_Full.prop)

shapiro.test(TolData$Score_Full.prop)

    Shapiro-Wilk normality test

data:  TolData$Score_Full.prop
W = 0.90488, p-value = 6.821e-05
#Not Normal

##Try square transformation
hist((TolData$Score_Full.prop)^2)

shapiro.test((TolData$Score_Full.prop)^2)

    Shapiro-Wilk normality test

data:  (TolData$Score_Full.prop)^2
W = 0.9194, p-value = 0.0002754
#Not normal 

##Try cubed transformation
hist((TolData$Score_Full.prop)^3)

shapiro.test((TolData$Score_Full.prop)^3)

    Shapiro-Wilk normality test

data:  (TolData$Score_Full.prop)^3
W = 0.91645, p-value = 0.0002055
#Not normal 


##Model as a function of Site and Genotype and Timepoint
##Model with no transformation and check residuals
Tol_ScoreF_lm<-lm(Score_Full.prop~Site+Genotype+TimeP+ Site:Genotype + Site:TimeP + Genotype:TimeP, data=TolData)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreF_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreF_lm)); qqline(resid(Tol_ScoreF_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreF_lm), resid(Tol_ScoreF_lm))

Residuals are not great, need to check for other modeling options for Color Full Set.

Model Results

#Model Results
summary(Tol_ScoreF_lm)

Call:
lm(formula = Score_Full.prop ~ Site + Genotype + TimeP + Site:Genotype + 
    Site:TimeP + Genotype:TimeP, data = TolData)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.217253 -0.020809  0.001419  0.037990  0.181147 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)         0.816721   0.010646  76.716  < 2e-16 ***
Site.L              0.068538   0.015014   4.565 2.85e-05 ***
Genotype.L         -0.162107   0.018189  -8.912 2.92e-12 ***
Genotype.Q         -0.000730   0.018686  -0.039  0.96898    
TimeP.L             0.143092   0.018189   7.867 1.44e-10 ***
TimeP.Q            -0.021653   0.018686  -1.159  0.25157    
Site.L:Genotype.L   0.033429   0.025724   1.300  0.19918    
Site.L:Genotype.Q  -0.007619   0.026324  -0.289  0.77333    
Site.L:TimeP.L     -0.039262   0.025724  -1.526  0.13267    
Site.L:TimeP.Q     -0.005353   0.026324  -0.203  0.83961    
Genotype.L:TimeP.L  0.055269   0.031703   1.743  0.08686 .  
Genotype.Q:TimeP.L  0.032487   0.031306   1.038  0.30393    
Genotype.L:TimeP.Q -0.003858   0.031306  -0.123  0.90237    
Genotype.Q:TimeP.Q -0.108144   0.033392  -3.239  0.00204 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.08798 on 55 degrees of freedom
Multiple R-squared:  0.7679,    Adjusted R-squared:  0.7131 
F-statistic:    14 on 13 and 55 DF,  p-value: 4.691e-13
anova(Tol_ScoreF_lm)
Analysis of Variance Table

Response: Score_Full.prop
               Df  Sum Sq  Mean Sq F value    Pr(>F)    
Site            1 0.18599 0.185989 24.0291 8.773e-06 ***
Genotype        2 0.58580 0.292900 37.8415 4.613e-11 ***
TimeP           2 0.48992 0.244959 31.6477 7.135e-10 ***
Site:Genotype   2 0.01497 0.007484  0.9669   0.38664    
Site:TimeP      2 0.02075 0.010376  1.3405   0.27013    
Genotype:TimeP  4 0.11112 0.027780  3.5891   0.01137 *  
Residuals      55 0.42571 0.007740                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreF_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter      |     Eta2 |       95% CI
----------------------------------------
Site           |     0.10 | [0.01, 1.00]
Genotype       |     0.32 | [0.15, 1.00]
TimeP          |     0.27 | [0.10, 1.00]
Site:Genotype  | 8.16e-03 | [0.00, 1.00]
Site:TimeP     |     0.01 | [0.00, 1.00]
Genotype:TimeP |     0.06 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreF_lm.res<-data.frame(anova(Tol_ScoreF_lm))
Tol_ScoreF_lm.res$Predictor<-rownames(Tol_ScoreF_lm.res)
Tol_ScoreF_lm.res$EtaSq<-c(eta_squared(Tol_ScoreF_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreF_lm.res$Response<-rep("Color_FullSet", nrow(Tol_ScoreF_lm.res))
Tol_ScoreF_lm.res<-Tol_ScoreF_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Strong influence of Timepoint, including interactions with Genotype. Will analyze each Timepoint individually.

Color Score Full Set Summer 1 Timepoint W2

Run Model

##Check normality
hist(TolData_W2$Score_Full.prop)

shapiro.test(TolData_W2$Score_Full.prop)

    Shapiro-Wilk normality test

data:  TolData_W2$Score_Full.prop
W = 0.96098, p-value = 0.4834
#Normal

##Model as a function of Site and Genotype
Tol_ScoreF_W2_lm<-lm(Score_Full.prop~Site+Genotype+Site:Genotype, data=TolData_W2)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreF_W2_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreF_W2_lm)); qqline(resid(Tol_ScoreF_W2_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreF_W2_lm), resid(Tol_ScoreF_W2_lm))

Model Results

Overall

#Model Results
summary(Tol_ScoreF_W2_lm)

Call:
lm(formula = Score_Full.prop ~ Site + Genotype + Site:Genotype, 
    data = TolData_W2)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.20185 -0.04952 -0.00045  0.04135  0.16725 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.706208   0.023330  30.270 3.15e-16 ***
Site.L             0.093421   0.032994   2.831 0.011517 *  
Genotype.L        -0.203806   0.040938  -4.978 0.000115 ***
Genotype.Q        -0.068453   0.039874  -1.717 0.104193    
Site.L:Genotype.L  0.003375   0.057895   0.058 0.954193    
Site.L:Genotype.Q  0.010407   0.056391   0.185 0.855768    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.1112 on 17 degrees of freedom
Multiple R-squared:  0.6882,    Adjusted R-squared:  0.5964 
F-statistic: 7.503 on 5 and 17 DF,  p-value: 7e-04
anova(Tol_ScoreF_W2_lm)
Analysis of Variance Table

Response: Score_Full.prop
              Df  Sum Sq  Mean Sq F value    Pr(>F)    
Site           1 0.12458 0.124577 10.0661 0.0055647 ** 
Genotype       2 0.33925 0.169625 13.7060 0.0002851 ***
Site:Genotype  2 0.00045 0.000226  0.0183 0.9819098    
Residuals     17 0.21039 0.012376                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreF_W2_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     |     Eta2 |       95% CI
---------------------------------------
Site          |     0.18 | [0.00, 1.00]
Genotype      |     0.50 | [0.17, 1.00]
Site:Genotype | 6.70e-04 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreF_W2_lm.res<-data.frame(anova(Tol_ScoreF_W2_lm))
Tol_ScoreF_W2_lm.res$Predictor<-rownames(Tol_ScoreF_W2_lm.res)
Tol_ScoreF_W2_lm.res$EtaSq<-c(eta_squared(Tol_ScoreF_W2_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreF_W2_lm.res$Response<-rep("Color_FullSet", nrow(Tol_ScoreF_W2_lm.res))
Tol_ScoreF_W2_lm.res$TimeP<-rep("W2", nrow(Tol_ScoreF_W2_lm.res))
Tol_ScoreF_W2_lm.res<-Tol_ScoreF_W2_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Site and Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_ScoreF_W2_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.755 0.0556 17    0.638    0.872
 AC12      0.702 0.0556 17    0.585    0.819
 AC8       0.463 0.0556 17    0.346    0.581

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.890 0.0556 17    0.772    1.007
 AC12      0.822 0.0556 17    0.705    0.940
 AC8       0.605 0.0642 17    0.469    0.740

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0529 0.0787 17   0.673  0.7820
 AC10 - AC8    0.2916 0.0787 17   3.707  0.0047
 AC12 - AC8    0.2387 0.0787 17   3.034  0.0195

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0676 0.0787 17   0.859  0.6723
 AC10 - AC8    0.2848 0.0850 17   3.353  0.0100
 AC12 - AC8    0.2172 0.0850 17   2.557  0.0508

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_ScoreF_W2_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.755 0.0556 17    0.638    0.872
 SS    0.890 0.0556 17    0.772    1.007

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    0.702 0.0556 17    0.585    0.819
 SS    0.822 0.0556 17    0.705    0.940

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.463 0.0556 17    0.346    0.581
 SS    0.605 0.0642 17    0.469    0.740

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS    -0.135 0.0787 17  -1.713  0.1049

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS    -0.120 0.0787 17  -1.527  0.1452

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS    -0.141 0.0850 17  -1.665  0.1142
##Save p-values

#Genotypes within Sites
Tol_ScoreF_W2_lm.geno<-data.frame(emmeans(Tol_ScoreF_W2_lm, pairwise~Genotype | Site)$contrasts)
Tol_ScoreF_W2_lm.geno<-Tol_ScoreF_W2_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreF_W2_lm.geno$group1<-paste(Tol_ScoreF_W2_lm.geno$Site, Tol_ScoreF_W2_lm.geno$group1, sep="_")
Tol_ScoreF_W2_lm.geno$group2<-paste(Tol_ScoreF_W2_lm.geno$Site, Tol_ScoreF_W2_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_ScoreF_W2_lm.site<-data.frame(emmeans(Tol_ScoreF_W2_lm, pairwise~Site | Genotype)$contrasts)
Tol_ScoreF_W2_lm.site<-Tol_ScoreF_W2_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreF_W2_lm.site$group1<-paste(Tol_ScoreF_W2_lm.site$group1, Tol_ScoreF_W2_lm.site$Genotype, sep="_")
Tol_ScoreF_W2_lm.site$group2<-paste(Tol_ScoreF_W2_lm.site$group2, Tol_ScoreF_W2_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_ScoreF_W2_lm.p<-rbind(Tol_ScoreF_W2_lm.geno[,c(1:2,4:8)], Tol_ScoreF_W2_lm.site[,c(1:2,4:8)])
Tol_ScoreF_W2_lm.p<-Tol_ScoreF_W2_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_ScoreF_W2_lm.p$Sig<-ifelse(Tol_ScoreF_W2_lm.p$p<0.001, "***", ifelse(Tol_ScoreF_W2_lm.p$p<0.01, "**", ifelse(Tol_ScoreF_W2_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_ScoreF_W2_lm.p$Response<-rep("Color_FullSet", nrow(Tol_ScoreF_W2_lm.p))
Tol_ScoreF_W2_lm.p$TimeP<-rep("W2", nrow(Tol_ScoreF_W2_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_ScoreF_W2_SG<-summarySE(TolData_W2, measurevar="Score_Full.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_ScoreF_W2_SG.plot<-ggplot(Tol_ScoreF_W2_SG, aes(x=Site.Geno, y=Score_Full.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_Full.prop-se, ymax=Score_Full.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Color Retention Full Set")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
  ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreF_W2_lm.p,  y.position=0.9, step.increase=0.35, label="Sig", hide.ns=TRUE); Tol_ScoreF_W2_SG.plot

Color Score Full Set Summer 2 Timepoint M1

Run Model

##Check normality
hist(TolData_M1$Score_Full.prop)

shapiro.test(TolData_M1$Score_Full.prop)

    Shapiro-Wilk normality test

data:  TolData_M1$Score_Full.prop
W = 0.89042, p-value = 0.01921
#Not normal

##Try square transformation
hist((TolData_M1$Score_Full.prop)^2)

shapiro.test((TolData_M1$Score_Full.prop)^2)

    Shapiro-Wilk normality test

data:  (TolData_M1$Score_Full.prop)^2
W = 0.89427, p-value = 0.02287
#Not normal

##Try cubed transformation
hist((TolData_M1$Score_Full.prop)^3)

shapiro.test((TolData_M1$Score_Full.prop)^3)

    Shapiro-Wilk normality test

data:  (TolData_M1$Score_Full.prop)^3
W = 0.88949, p-value = 0.01842
#Not normal

##Model as a function of Site and Genotype
##Model with no transformation and check residuals
Tol_ScoreF_M1_lm<-lm(Score_Full.prop~Site+Genotype+Site:Genotype, data=TolData_M1)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreF_M1_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreF_M1_lm)); qqline(resid(Tol_ScoreF_M1_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreF_M1_lm), resid(Tol_ScoreF_M1_lm))

Model Results

Overall

#Model Results
summary(Tol_ScoreF_M1_lm)

Call:
lm(formula = Score_Full.prop ~ Site + Genotype + Site:Genotype, 
    data = TolData_M1)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.205567 -0.027956  0.001925  0.027094  0.192833 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.83440    0.02043  40.846  < 2e-16 ***
Site.L             0.07153    0.02889   2.476 0.024843 *  
Genotype.L        -0.15896    0.03357  -4.736 0.000224 ***
Genotype.Q         0.08757    0.03711   2.360 0.031325 *  
Site.L:Genotype.L  0.07642    0.04747   1.610 0.126961    
Site.L:Genotype.Q  0.01094    0.05248   0.208 0.837562    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.09494 on 16 degrees of freedom
Multiple R-squared:  0.6982,    Adjusted R-squared:  0.6039 
F-statistic: 7.403 on 5 and 16 DF,  p-value: 0.0009114
anova(Tol_ScoreF_M1_lm)
Analysis of Variance Table

Response: Score_Full.prop
              Df   Sum Sq  Mean Sq F value    Pr(>F)    
Site           1 0.057569 0.057569  6.3867 0.0224118 *  
Genotype       2 0.252333 0.126167 13.9969 0.0003061 ***
Site:Genotype  2 0.023755 0.011877  1.3177 0.2952999    
Residuals     16 0.144222 0.009014                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreF_M1_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     | Eta2 |       95% CI
-----------------------------------
Site          | 0.12 | [0.00, 1.00]
Genotype      | 0.53 | [0.19, 1.00]
Site:Genotype | 0.05 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreF_M1_lm.res<-data.frame(anova(Tol_ScoreF_M1_lm))
Tol_ScoreF_M1_lm.res$Predictor<-rownames(Tol_ScoreF_M1_lm.res)
Tol_ScoreF_M1_lm.res$EtaSq<-c(eta_squared(Tol_ScoreF_M1_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreF_M1_lm.res$Response<-rep("Color_FullSet", nrow(Tol_ScoreF_M1_lm.res))
Tol_ScoreF_M1_lm.res$TimeP<-rep("M1", nrow(Tol_ScoreF_M1_lm.res))
Tol_ScoreF_M1_lm.res<-Tol_ScoreF_M1_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Site and Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_ScoreF_M1_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.967 0.0475 16    0.866    1.068
 AC12      0.719 0.0548 16    0.602    0.835
 AC8       0.666 0.0475 16    0.565    0.766

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.998 0.0475 16    0.897    1.099
 AC12      0.807 0.0548 16    0.691    0.923
 AC8       0.850 0.0475 16    0.749    0.950

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.2484 0.0725 16   3.425  0.0092
 AC10 - AC8    0.3012 0.0671 16   4.487  0.0010
 AC12 - AC8    0.0528 0.0725 16   0.729  0.7504

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.1909 0.0725 16   2.633  0.0452
 AC10 - AC8    0.1484 0.0671 16   2.210  0.0998
 AC12 - AC8   -0.0425 0.0725 16  -0.587  0.8292

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_ScoreF_M1_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.967 0.0475 16    0.866    1.068
 SS    0.998 0.0475 16    0.897    1.099

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    0.719 0.0548 16    0.602    0.835
 SS    0.807 0.0548 16    0.691    0.923

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.666 0.0475 16    0.565    0.766
 SS    0.850 0.0475 16    0.749    0.950

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0311 0.0671 16  -0.463  0.6499

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0885 0.0775 16  -1.142  0.2702

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.1839 0.0671 16  -2.739  0.0146
##Save p-values

#Genotypes within Sites
Tol_ScoreF_M1_lm.geno<-data.frame(emmeans(Tol_ScoreF_M1_lm, pairwise~Genotype | Site)$contrasts)
Tol_ScoreF_M1_lm.geno<-Tol_ScoreF_M1_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreF_M1_lm.geno$group1<-paste(Tol_ScoreF_M1_lm.geno$Site, Tol_ScoreF_M1_lm.geno$group1, sep="_")
Tol_ScoreF_M1_lm.geno$group2<-paste(Tol_ScoreF_M1_lm.geno$Site, Tol_ScoreF_M1_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_ScoreF_M1_lm.site<-data.frame(emmeans(Tol_ScoreF_M1_lm, pairwise~Site | Genotype)$contrasts)
Tol_ScoreF_M1_lm.site<-Tol_ScoreF_M1_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreF_M1_lm.site$group1<-paste(Tol_ScoreF_M1_lm.site$group1, Tol_ScoreF_M1_lm.site$Genotype, sep="_")
Tol_ScoreF_M1_lm.site$group2<-paste(Tol_ScoreF_M1_lm.site$group2, Tol_ScoreF_M1_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_ScoreF_M1_lm.p<-rbind(Tol_ScoreF_M1_lm.geno[,c(1:2,4:8)], Tol_ScoreF_M1_lm.site[,c(1:2,4:8)])
Tol_ScoreF_M1_lm.p<-Tol_ScoreF_M1_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_ScoreF_M1_lm.p$Sig<-ifelse(Tol_ScoreF_M1_lm.p$p<0.001, "***", ifelse(Tol_ScoreF_M1_lm.p$p<0.01, "**", ifelse(Tol_ScoreF_M1_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_ScoreF_M1_lm.p$Response<-rep("Color_FullSet", nrow(Tol_ScoreF_M1_lm.p))
Tol_ScoreF_M1_lm.p$TimeP<-rep("M1", nrow(Tol_ScoreF_M1_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_ScoreF_M1_SG<-summarySE(TolData_M1, measurevar="Score_Full.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_ScoreF_M1_SG.plot<-ggplot(Tol_ScoreF_M1_SG, aes(x=Site.Geno, y=Score_Full.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_Full.prop-se, ymax=Score_Full.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Color Retention Full Set")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
 ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreF_M1_lm.p,  y.position=1.1, step.increase=0.2, label="Sig", hide.ns=TRUE); Tol_ScoreF_M1_SG.plot

Color Score Full Set Winter Timepoint M4

Run Model

##Check normality
hist(TolData_M4$Score_Full.prop)

shapiro.test(TolData_M4$Score_Full.prop)

    Shapiro-Wilk normality test

data:  TolData_M4$Score_Full.prop
W = 0.83109, p-value = 0.0009936
#Not Normal

##Try square transformation
hist((TolData_M4$Score_Full.prop)^2)

shapiro.test((TolData_M4$Score_Full.prop)^2)

    Shapiro-Wilk normality test

data:  (TolData_M4$Score_Full.prop)^2
W = 0.8317, p-value = 0.001019
#Not Normal

##Try cubed transformation
hist((TolData_M4$Score_Full.prop)^3)

shapiro.test((TolData_M4$Score_Full.prop)^3)

    Shapiro-Wilk normality test

data:  (TolData_M4$Score_Full.prop)^3
W = 0.83161, p-value = 0.001015
#Not Normal

##Model as a function of Site and Genotype
##Model with no transformation and check residuals
Tol_ScoreF_M4_lm<-lm(Score_Full.prop~Site+Genotype+Site:Genotype, data=TolData_M4)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreF_M4_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreF_M4_lm)); qqline(resid(Tol_ScoreF_M4_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreF_M4_lm), resid(Tol_ScoreF_M4_lm))

Model Results

Overall

#Model Results
summary(Tol_ScoreF_M4_lm)

Call:
lm(formula = Score_Full.prop ~ Site + Genotype + Site:Genotype, 
    data = TolData_M4)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.137800 -0.019025  0.003675  0.020575  0.099500 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.90906    0.01100  82.614  < 2e-16 ***
Site.L             0.03859    0.01556   2.480   0.0233 *  
Genotype.L        -0.12460    0.01906  -6.538 3.82e-06 ***
Genotype.Q        -0.02191    0.01906  -1.149   0.2654    
Site.L:Genotype.L  0.01901    0.02695   0.705   0.4896    
Site.L:Genotype.Q -0.04168    0.02695  -1.546   0.1394    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.05391 on 18 degrees of freedom
Multiple R-squared:  0.7468,    Adjusted R-squared:  0.6765 
F-statistic: 10.62 on 5 and 18 DF,  p-value: 7.153e-05
anova(Tol_ScoreF_M4_lm)
Analysis of Variance Table

Response: Score_Full.prop
              Df   Sum Sq  Mean Sq F value    Pr(>F)    
Site           1 0.017871 0.017871  6.1496   0.02326 *  
Genotype       2 0.128043 0.064021 22.0308 1.452e-05 ***
Site:Genotype  2 0.008394 0.004197  1.4442   0.26199    
Residuals     18 0.052308 0.002906                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreF_M4_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     | Eta2 |       95% CI
-----------------------------------
Site          | 0.09 | [0.00, 1.00]
Genotype      | 0.62 | [0.34, 1.00]
Site:Genotype | 0.04 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreF_M4_lm.res<-data.frame(anova(Tol_ScoreF_M4_lm))
Tol_ScoreF_M4_lm.res$Predictor<-rownames(Tol_ScoreF_M4_lm.res)
Tol_ScoreF_M4_lm.res$EtaSq<-c(eta_squared(Tol_ScoreF_M4_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreF_M4_lm.res$Response<-rep("Color_FullSet", nrow(Tol_ScoreF_M4_lm.res))
Tol_ScoreF_M4_lm.res$TimeP<-rep("M4", nrow(Tol_ScoreF_M4_lm.res))
Tol_ScoreF_M4_lm.res<-Tol_ScoreF_M4_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Site and Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_ScoreF_M4_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean    SE df lower.CL upper.CL
 AC10      0.982 0.027 18    0.926    1.039
 AC12      0.876 0.027 18    0.819    0.932
 AC8       0.787 0.027 18    0.731    0.844

Site = SS:
 Genotype emmean    SE df lower.CL upper.CL
 AC10      0.994 0.027 18    0.937    1.051
 AC12      0.978 0.027 18    0.922    1.035
 AC8       0.837 0.027 18    0.780    0.893

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.1069 0.0381 18   2.804  0.0301
 AC10 - AC8    0.1952 0.0381 18   5.122  0.0002
 AC12 - AC8    0.0883 0.0381 18   2.318  0.0788

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0157 0.0381 18   0.411  0.9115
 AC10 - AC8    0.1572 0.0381 18   4.124  0.0018
 AC12 - AC8    0.1415 0.0381 18   3.713  0.0043

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_ScoreF_M4_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean    SE df lower.CL upper.CL
 KL    0.982 0.027 18    0.926    1.039
 SS    0.994 0.027 18    0.937    1.051

Genotype = AC12:
 Site emmean    SE df lower.CL upper.CL
 KL    0.876 0.027 18    0.819    0.932
 SS    0.978 0.027 18    0.922    1.035

Genotype = AC8:
 Site emmean    SE df lower.CL upper.CL
 KL    0.787 0.027 18    0.731    0.844
 SS    0.837 0.027 18    0.780    0.893

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0115 0.0381 18  -0.302  0.7663

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.1027 0.0381 18  -2.694  0.0148

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0495 0.0381 18  -1.299  0.2103
##Save p-values

#Genotypes within Sites
Tol_ScoreF_M4_lm.geno<-data.frame(emmeans(Tol_ScoreF_M4_lm, pairwise~Genotype | Site)$contrasts)
Tol_ScoreF_M4_lm.geno<-Tol_ScoreF_M4_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreF_M4_lm.geno$group1<-paste(Tol_ScoreF_M4_lm.geno$Site, Tol_ScoreF_M4_lm.geno$group1, sep="_")
Tol_ScoreF_M4_lm.geno$group2<-paste(Tol_ScoreF_M4_lm.geno$Site, Tol_ScoreF_M4_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_ScoreF_M4_lm.site<-data.frame(emmeans(Tol_ScoreF_M4_lm, pairwise~Site | Genotype)$contrasts)
Tol_ScoreF_M4_lm.site<-Tol_ScoreF_M4_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreF_M4_lm.site$group1<-paste(Tol_ScoreF_M4_lm.site$group1, Tol_ScoreF_M4_lm.site$Genotype, sep="_")
Tol_ScoreF_M4_lm.site$group2<-paste(Tol_ScoreF_M4_lm.site$group2, Tol_ScoreF_M4_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_ScoreF_M4_lm.p<-rbind(Tol_ScoreF_M4_lm.geno[,c(1:2,4:8)], Tol_ScoreF_M4_lm.site[,c(1:2,4:8)])
Tol_ScoreF_M4_lm.p<-Tol_ScoreF_M4_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_ScoreF_M4_lm.p$Sig<-ifelse(Tol_ScoreF_M4_lm.p$p<0.001, "***", ifelse(Tol_ScoreF_M4_lm.p$p<0.01, "**", ifelse(Tol_ScoreF_M4_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_ScoreF_M4_lm.p$Response<-rep("Color_FullSet", nrow(Tol_ScoreF_M4_lm.p))
Tol_ScoreF_M4_lm.p$TimeP<-rep("M4", nrow(Tol_ScoreF_M4_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_ScoreF_M4_SG<-summarySE(TolData_M4, measurevar="Score_Full.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_ScoreF_M4_SG.plot<-ggplot(Tol_ScoreF_M4_SG, aes(x=Site.Geno, y=Score_Full.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_Full.prop-se, ymax=Score_Full.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Color Retention Full Set")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
  ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreF_M4_lm.p,  y.position=1.1, step.increase=0.22, label="Sig", hide.ns=TRUE); Tol_ScoreF_M4_SG.plot

Thermal Tolerance Color by Timepoint

Full Set

Run Model

##Check normality
hist(TolData$Score_TP.prop)

shapiro.test(TolData$Score_TP.prop)

    Shapiro-Wilk normality test

data:  TolData$Score_TP.prop
W = 0.9161, p-value = 0.0001986
#Not Normal

##Try square transformation
hist((TolData$Score_TP.prop)^2)

shapiro.test((TolData$Score_TP.prop)^2)

    Shapiro-Wilk normality test

data:  (TolData$Score_TP.prop)^2
W = 0.92506, p-value = 0.0004895
#Not normal 

##Try cubed transformation
hist((TolData$Score_TP.prop)^3)

shapiro.test((TolData$Score_TP.prop)^3)

    Shapiro-Wilk normality test

data:  (TolData$Score_TP.prop)^3
W = 0.92936, p-value = 0.0007674
#Not normal 


##Model as a function of Site and Genotype and Timepoint
##Model with no transformation and check residuals
Tol_ScoreTP_lm<-lm(Score_TP.prop~Site+Genotype+TimeP+ Site:Genotype + Site:TimeP + Genotype:TimeP, data=TolData)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreTP_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreTP_lm)); qqline(resid(Tol_ScoreTP_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreTP_lm), resid(Tol_ScoreTP_lm))

Residuals are not great, need to check for other modeling options for Color by Timepoint.

Model Results

#Model Results
summary(Tol_ScoreTP_lm)

Call:
lm(formula = Score_TP.prop ~ Site + Genotype + TimeP + Site:Genotype + 
    Site:TimeP + Genotype:TimeP, data = TolData)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.133294 -0.019060  0.000725  0.026225  0.122906 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)         0.883494   0.006319 139.809  < 2e-16 ***
Site.L              0.038546   0.008912   4.325 6.47e-05 ***
Genotype.L         -0.102221   0.010797  -9.468 3.81e-13 ***
Genotype.Q          0.004971   0.011092   0.448 0.655784    
TimeP.L             0.068495   0.010797   6.344 4.45e-08 ***
TimeP.Q             0.021265   0.011092   1.917 0.060411 .  
Site.L:Genotype.L   0.014004   0.015269   0.917 0.363050    
Site.L:Genotype.Q  -0.008574   0.015625  -0.549 0.585424    
Site.L:TimeP.L     -0.036792   0.015269  -2.410 0.019344 *  
Site.L:TimeP.Q     -0.004886   0.015625  -0.313 0.755697    
Genotype.L:TimeP.L  0.029281   0.018818   1.556 0.125448    
Genotype.Q:TimeP.L  0.024642   0.018582   1.326 0.190292    
Genotype.L:TimeP.Q  0.015340   0.018582   0.826 0.412653    
Genotype.Q:TimeP.Q -0.072757   0.019821  -3.671 0.000548 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.05222 on 55 degrees of freedom
Multiple R-squared:  0.763, Adjusted R-squared:  0.7069 
F-statistic: 13.62 on 13 and 55 DF,  p-value: 8.098e-13
anova(Tol_ScoreTP_lm)
Analysis of Variance Table

Response: Score_TP.prop
               Df   Sum Sq  Mean Sq F value    Pr(>F)    
Site            1 0.057199 0.057199 20.9741 2.709e-05 ***
Genotype        2 0.238412 0.119206 43.7110 4.331e-12 ***
TimeP           2 0.117103 0.058552 21.4700 1.284e-07 ***
Site:Genotype   2 0.003221 0.001611  0.5906  0.557481    
Site:TimeP      2 0.017283 0.008642  3.1687  0.049832 *  
Genotype:TimeP  4 0.049580 0.012395  4.5450  0.003041 ** 
Residuals      55 0.149993 0.002727                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreTP_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter      |     Eta2 |       95% CI
----------------------------------------
Site           |     0.09 | [0.01, 1.00]
Genotype       |     0.38 | [0.20, 1.00]
TimeP          |     0.19 | [0.04, 1.00]
Site:Genotype  | 5.09e-03 | [0.00, 1.00]
Site:TimeP     |     0.03 | [0.00, 1.00]
Genotype:TimeP |     0.08 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreTP_lm.res<-data.frame(anova(Tol_ScoreTP_lm))
Tol_ScoreTP_lm.res$Predictor<-rownames(Tol_ScoreTP_lm.res)
Tol_ScoreTP_lm.res$EtaSq<-c(eta_squared(Tol_ScoreTP_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreTP_lm.res$Response<-rep("Color_TP", nrow(Tol_ScoreTP_lm.res))
Tol_ScoreTP_lm.res<-Tol_ScoreTP_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Strong influence of Timepoint, including interactions with variables of interest, Site and Genotype. Will analyze each Timepoint individually.

Color Score by Timepoint Summer 1 Timepoint W2

Run Model

##Check normality
hist(TolData_W2$Score_TP.prop)

shapiro.test(TolData_W2$Score_TP.prop)

    Shapiro-Wilk normality test

data:  TolData_W2$Score_TP.prop
W = 0.95832, p-value = 0.4302
#Normal

##Model as a function of Site and Genotype
Tol_ScoreTP_W2_lm<-lm(Score_TP.prop~Site+Genotype+Site:Genotype, data=TolData_W2)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreTP_W2_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreTP_W2_lm)); qqline(resid(Tol_ScoreTP_W2_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreTP_W2_lm), resid(Tol_ScoreTP_W2_lm))

Model Results

Overall

#Model Results
summary(Tol_ScoreTP_W2_lm)

Call:
lm(formula = Score_TP.prop ~ Site + Genotype + Site:Genotype, 
    data = TolData_W2)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.117075 -0.028442 -0.002075  0.023658  0.099425 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.843522   0.013080  64.488  < 2e-16 ***
Site.L             0.062257   0.018498   3.366  0.00367 ** 
Genotype.L        -0.117129   0.022952  -5.103 8.83e-05 ***
Genotype.Q        -0.042426   0.022356  -1.898  0.07485 .  
Site.L:Genotype.L -0.002071   0.032459  -0.064  0.94987    
Site.L:Genotype.Q  0.004044   0.031616   0.128  0.89972    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.06237 on 17 degrees of freedom
Multiple R-squared:  0.7169,    Adjusted R-squared:  0.6336 
F-statistic:  8.61 on 5 and 17 DF,  p-value: 0.0003242
anova(Tol_ScoreTP_W2_lm)
Analysis of Variance Table

Response: Score_TP.prop
              Df   Sum Sq  Mean Sq F value    Pr(>F)    
Site           1 0.054151 0.054151 13.9200 0.0016623 ** 
Genotype       2 0.113242 0.056621 14.5549 0.0002073 ***
Site:Genotype  2 0.000083 0.000041  0.0106 0.9894534    
Residuals     17 0.066133 0.003890                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreTP_W2_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     |     Eta2 |       95% CI
---------------------------------------
Site          |     0.23 | [0.01, 1.00]
Genotype      |     0.48 | [0.15, 1.00]
Site:Genotype | 3.53e-04 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreTP_W2_lm.res<-data.frame(anova(Tol_ScoreTP_W2_lm))
Tol_ScoreTP_W2_lm.res$Predictor<-rownames(Tol_ScoreTP_W2_lm.res)
Tol_ScoreTP_W2_lm.res$EtaSq<-c(eta_squared(Tol_ScoreTP_W2_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreTP_W2_lm.res$Response<-rep("Color_TP", nrow(Tol_ScoreTP_W2_lm.res))
Tol_ScoreTP_W2_lm.res$TimeP<-rep("W2", nrow(Tol_ScoreTP_W2_lm.res))
Tol_ScoreTP_W2_lm.res<-Tol_ScoreTP_W2_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Site and Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_ScoreTP_W2_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.863 0.0312 17    0.797    0.929
 AC12      0.836 0.0312 17    0.771    0.902
 AC8       0.699 0.0312 17    0.633    0.765

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.955 0.0312 17    0.889    1.021
 AC12      0.920 0.0312 17    0.854    0.986
 AC8       0.788 0.0360 17    0.712    0.864

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0263 0.0441 17   0.597  0.8236
 AC10 - AC8    0.1636 0.0441 17   3.709  0.0047
 AC12 - AC8    0.1373 0.0441 17   3.112  0.0166

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0354 0.0441 17   0.803  0.7065
 AC10 - AC8    0.1677 0.0476 17   3.521  0.0070
 AC12 - AC8    0.1323 0.0476 17   2.778  0.0328

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_ScoreTP_W2_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.863 0.0312 17    0.797    0.929
 SS    0.955 0.0312 17    0.889    1.021

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    0.836 0.0312 17    0.771    0.902
 SS    0.920 0.0312 17    0.854    0.986

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.699 0.0312 17    0.633    0.765
 SS    0.788 0.0360 17    0.712    0.864

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0925 0.0441 17  -2.096  0.0513

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0834 0.0441 17  -1.890  0.0759

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0883 0.0476 17  -1.854  0.0812
##Save p-values

#Genotypes within Sites
Tol_ScoreTP_W2_lm.geno<-data.frame(emmeans(Tol_ScoreTP_W2_lm, pairwise~Genotype | Site)$contrasts)
Tol_ScoreTP_W2_lm.geno<-Tol_ScoreTP_W2_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreTP_W2_lm.geno$group1<-paste(Tol_ScoreTP_W2_lm.geno$Site, Tol_ScoreTP_W2_lm.geno$group1, sep="_")
Tol_ScoreTP_W2_lm.geno$group2<-paste(Tol_ScoreTP_W2_lm.geno$Site, Tol_ScoreTP_W2_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_ScoreTP_W2_lm.site<-data.frame(emmeans(Tol_ScoreTP_W2_lm, pairwise~Site | Genotype)$contrasts)
Tol_ScoreTP_W2_lm.site<-Tol_ScoreTP_W2_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreTP_W2_lm.site$group1<-paste(Tol_ScoreTP_W2_lm.site$group1, Tol_ScoreTP_W2_lm.site$Genotype, sep="_")
Tol_ScoreTP_W2_lm.site$group2<-paste(Tol_ScoreTP_W2_lm.site$group2, Tol_ScoreTP_W2_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_ScoreTP_W2_lm.p<-rbind(Tol_ScoreTP_W2_lm.geno[,c(1:2,4:8)], Tol_ScoreTP_W2_lm.site[,c(1:2,4:8)])
Tol_ScoreTP_W2_lm.p<-Tol_ScoreTP_W2_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_ScoreTP_W2_lm.p$Sig<-ifelse(Tol_ScoreTP_W2_lm.p$p<0.001, "***", ifelse(Tol_ScoreTP_W2_lm.p$p<0.01, "**", ifelse(Tol_ScoreTP_W2_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_ScoreTP_W2_lm.p$Response<-rep("Color_TP", nrow(Tol_ScoreTP_W2_lm.p))
Tol_ScoreTP_W2_lm.p$TimeP<-rep("W2", nrow(Tol_ScoreTP_W2_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_ScoreTP_W2_SG<-summarySE(TolData_W2, measurevar="Score_TP.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_ScoreTP_W2_SG.plot<-ggplot(Tol_ScoreTP_W2_SG, aes(x=Site.Geno, y=Score_TP.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_TP.prop-se, ymax=Score_TP.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Color Retention by Timepoint")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
  ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreTP_W2_lm.p,  y.position=1, step.increase=0.45, label="Sig", hide.ns=TRUE); Tol_ScoreTP_W2_SG.plot

Color Score by Timepoint Summer 2 Timepoint M1

Run Model

##Check normality
hist(TolData_M1$Score_TP.prop)

shapiro.test(TolData_M1$Score_TP.prop)

    Shapiro-Wilk normality test

data:  TolData_M1$Score_TP.prop
W = 0.9028, p-value = 0.03383
#Not normal

##Try square transformation
hist((TolData_M1$Score_TP.prop)^2)

shapiro.test((TolData_M1$Score_TP.prop)^2)

    Shapiro-Wilk normality test

data:  (TolData_M1$Score_TP.prop)^2
W = 0.90185, p-value = 0.03238
#Not normal

##Try cubed transformation
hist((TolData_M1$Score_TP.prop)^3)

shapiro.test((TolData_M1$Score_TP.prop)^3)

    Shapiro-Wilk normality test

data:  (TolData_M1$Score_TP.prop)^3
W = 0.89818, p-value = 0.02735
#Not normal

##Model as a function of Site and Genotype
##Model with no transformation and check residuals
Tol_ScoreTP_M1_lm<-lm(Score_TP.prop~Site+Genotype+Site:Genotype, data=TolData_M1)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreTP_M1_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreTP_M1_lm)); qqline(resid(Tol_ScoreTP_M1_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreTP_M1_lm), resid(Tol_ScoreTP_M1_lm))

Model Results

Overall

#Model Results
summary(Tol_ScoreTP_M1_lm)

Call:
lm(formula = Score_TP.prop ~ Site + Genotype + Site:Genotype, 
    data = TolData_M1)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.125200 -0.020725 -0.001675  0.015662  0.131000 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.866131   0.012681  68.303  < 2e-16 ***
Site.L             0.041582   0.017933   2.319    0.034 *  
Genotype.L        -0.114746   0.020837  -5.507 4.78e-05 ***
Genotype.Q         0.064377   0.023036   2.795    0.013 *  
Site.L:Genotype.L  0.050375   0.029467   1.710    0.107    
Site.L:Genotype.Q  0.004277   0.032577   0.131    0.897    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.05893 on 16 degrees of freedom
Multiple R-squared:  0.7446,    Adjusted R-squared:  0.6647 
F-statistic: 9.327 on 5 and 16 DF,  p-value: 0.0002606
anova(Tol_ScoreTP_M1_lm)
Analysis of Variance Table

Response: Score_TP.prop
              Df   Sum Sq  Mean Sq F value    Pr(>F)    
Site           1 0.019311 0.019311  5.5598   0.03144 *  
Genotype       2 0.132460 0.066230 19.0683 5.822e-05 ***
Site:Genotype  2 0.010210 0.005105  1.4698   0.25940    
Residuals     16 0.055573 0.003473                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreTP_M1_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     | Eta2 |       95% CI
-----------------------------------
Site          | 0.09 | [0.00, 1.00]
Genotype      | 0.61 | [0.30, 1.00]
Site:Genotype | 0.05 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreTP_M1_lm.res<-data.frame(anova(Tol_ScoreTP_M1_lm))
Tol_ScoreTP_M1_lm.res$Predictor<-rownames(Tol_ScoreTP_M1_lm.res)
Tol_ScoreTP_M1_lm.res$EtaSq<-c(eta_squared(Tol_ScoreTP_M1_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreTP_M1_lm.res$Response<-rep("Color_TP", nrow(Tol_ScoreTP_M1_lm.res))
Tol_ScoreTP_M1_lm.res$TimeP<-rep("M1", nrow(Tol_ScoreTP_M1_lm.res))
Tol_ScoreTP_M1_lm.res<-Tol_ScoreTP_M1_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Site and Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_ScoreTP_M1_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.968 0.0295 16    0.906    1.031
 AC12      0.787 0.0340 16    0.715    0.859
 AC8       0.755 0.0295 16    0.693    0.818

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.979 0.0295 16    0.917    1.041
 AC12      0.841 0.0340 16    0.768    0.913
 AC8       0.867 0.0295 16    0.805    0.930

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.1815 0.0450 16   4.032  0.0026
 AC10 - AC8    0.2127 0.0417 16   5.103  0.0003
 AC12 - AC8    0.0312 0.0450 16   0.693  0.7710

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.1385 0.0450 16   3.077  0.0187
 AC10 - AC8    0.1119 0.0417 16   2.685  0.0408
 AC12 - AC8   -0.0266 0.0450 16  -0.591  0.8269

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_ScoreTP_M1_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.968 0.0295 16    0.906    1.031
 SS    0.979 0.0295 16    0.917    1.041

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    0.787 0.0340 16    0.715    0.859
 SS    0.841 0.0340 16    0.768    0.913

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.755 0.0295 16    0.693    0.818
 SS    0.867 0.0295 16    0.805    0.930

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0109 0.0417 16  -0.262  0.7970

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0539 0.0481 16  -1.119  0.2795

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.1116 0.0417 16  -2.679  0.0165
##Save p-values

#Genotypes within Sites
Tol_ScoreTP_M1_lm.geno<-data.frame(emmeans(Tol_ScoreTP_M1_lm, pairwise~Genotype | Site)$contrasts)
Tol_ScoreTP_M1_lm.geno<-Tol_ScoreTP_M1_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreTP_M1_lm.geno$group1<-paste(Tol_ScoreTP_M1_lm.geno$Site, Tol_ScoreTP_M1_lm.geno$group1, sep="_")
Tol_ScoreTP_M1_lm.geno$group2<-paste(Tol_ScoreTP_M1_lm.geno$Site, Tol_ScoreTP_M1_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_ScoreTP_M1_lm.site<-data.frame(emmeans(Tol_ScoreTP_M1_lm, pairwise~Site | Genotype)$contrasts)
Tol_ScoreTP_M1_lm.site<-Tol_ScoreTP_M1_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreTP_M1_lm.site$group1<-paste(Tol_ScoreTP_M1_lm.site$group1, Tol_ScoreTP_M1_lm.site$Genotype, sep="_")
Tol_ScoreTP_M1_lm.site$group2<-paste(Tol_ScoreTP_M1_lm.site$group2, Tol_ScoreTP_M1_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_ScoreTP_M1_lm.p<-rbind(Tol_ScoreTP_M1_lm.geno[,c(1:2,4:8)], Tol_ScoreTP_M1_lm.site[,c(1:2,4:8)])
Tol_ScoreTP_M1_lm.p<-Tol_ScoreTP_M1_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_ScoreTP_M1_lm.p$Sig<-ifelse(Tol_ScoreTP_M1_lm.p$p<0.001, "***", ifelse(Tol_ScoreTP_M1_lm.p$p<0.01, "**", ifelse(Tol_ScoreTP_M1_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_ScoreTP_M1_lm.p$Response<-rep("Color_TP", nrow(Tol_ScoreTP_M1_lm.p))
Tol_ScoreTP_M1_lm.p$TimeP<-rep("M1", nrow(Tol_ScoreTP_M1_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_ScoreTP_M1_SG<-summarySE(TolData_M1, measurevar="Score_TP.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_ScoreTP_M1_SG.plot<-ggplot(Tol_ScoreTP_M1_SG, aes(x=Site.Geno, y=Score_TP.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_TP.prop-se, ymax=Score_TP.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Color Retention by Timepoint")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
 ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreTP_M1_lm.p,  y.position=1.05, step.increase=0.3, label="Sig", hide.ns=TRUE); Tol_ScoreTP_M1_SG.plot

Color Score by Timepoint Winter Timepoint M4

Run Model

##Check normality
hist(TolData_M4$Score_TP.prop)

shapiro.test(TolData_M4$Score_TP.prop)

    Shapiro-Wilk normality test

data:  TolData_M4$Score_TP.prop
W = 0.85397, p-value = 0.002593
#Not Normal

##Try square transformation
hist((TolData_M4$Score_TP.prop)^2)

shapiro.test((TolData_M4$Score_TP.prop)^2)

    Shapiro-Wilk normality test

data:  (TolData_M4$Score_TP.prop)^2
W = 0.85439, p-value = 0.00264
#Not Normal

##Try cubed transformation
hist((TolData_M4$Score_TP.prop)^3)

shapiro.test((TolData_M4$Score_TP.prop)^3)

    Shapiro-Wilk normality test

data:  (TolData_M4$Score_TP.prop)^3
W = 0.85457, p-value = 0.002661
#Not Normal

##Model as a function of Site and Genotype
##Model with no transformation and check residuals
Tol_ScoreTP_M4_lm<-lm(Score_TP.prop~Site+Genotype+Site:Genotype, data=TolData_M4)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreTP_M4_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreTP_M4_lm)); qqline(resid(Tol_ScoreTP_M4_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreTP_M4_lm), resid(Tol_ScoreTP_M4_lm))

Model Results

Overall

#Model Results
summary(Tol_ScoreTP_M4_lm)

Call:
lm(formula = Score_TP.prop ~ Site + Genotype + Site:Genotype, 
    data = TolData_M4)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.070400 -0.009438  0.004100  0.011281  0.057100 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.940608   0.006243 150.654  < 2e-16 ***
Site.L             0.010536   0.008830   1.193   0.2483    
Genotype.L        -0.075254   0.010814  -6.959 1.68e-06 ***
Genotype.Q        -0.007308   0.010814  -0.676   0.5078    
Site.L:Genotype.L -0.006950   0.015293  -0.454   0.6549    
Site.L:Genotype.Q -0.032086   0.015293  -2.098   0.0503 .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.03059 on 18 degrees of freedom
Multiple R-squared:  0.7531,    Adjusted R-squared:  0.6846 
F-statistic: 10.98 on 5 and 18 DF,  p-value: 5.763e-05
anova(Tol_ScoreTP_M4_lm)
Analysis of Variance Table

Response: Score_TP.prop
              Df   Sum Sq   Mean Sq F value    Pr(>F)    
Site           1 0.001332 0.0013321  1.4238    0.2483    
Genotype       2 0.045732 0.0228662 24.4414 7.407e-06 ***
Site:Genotype  2 0.004311 0.0021557  2.3042    0.1285    
Residuals     18 0.016840 0.0009355                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreTP_M4_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     | Eta2 |       95% CI
-----------------------------------
Site          | 0.02 | [0.00, 1.00]
Genotype      | 0.67 | [0.41, 1.00]
Site:Genotype | 0.06 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreTP_M4_lm.res<-data.frame(anova(Tol_ScoreTP_M4_lm))
Tol_ScoreTP_M4_lm.res$Predictor<-rownames(Tol_ScoreTP_M4_lm.res)
Tol_ScoreTP_M4_lm.res$EtaSq<-c(eta_squared(Tol_ScoreTP_M4_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreTP_M4_lm.res$Response<-rep("Color_TP", nrow(Tol_ScoreTP_M4_lm.res))
Tol_ScoreTP_M4_lm.res$TimeP<-rep("M4", nrow(Tol_ScoreTP_M4_lm.res))
Tol_ScoreTP_M4_lm.res<-Tol_ScoreTP_M4_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_ScoreTP_M4_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.989 0.0153 18    0.957    1.021
 AC12      0.921 0.0153 18    0.888    0.953
 AC8       0.890 0.0153 18    0.858    0.922

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.993 0.0153 18    0.960    1.025
 AC12      0.973 0.0153 18    0.940    1.005
 AC8       0.879 0.0153 18    0.847    0.911

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0686 0.0216 18   3.171  0.0139
 AC10 - AC8    0.0995 0.0216 18   4.599  0.0006
 AC12 - AC8    0.0309 0.0216 18   1.429  0.3478

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0199 0.0216 18   0.922  0.6335
 AC10 - AC8    0.1134 0.0216 18   5.242  0.0002
 AC12 - AC8    0.0934 0.0216 18   4.320  0.0011

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_ScoreTP_M4_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.989 0.0153 18    0.957    1.021
 SS    0.993 0.0153 18    0.960    1.025

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    0.921 0.0153 18    0.888    0.953
 SS    0.973 0.0153 18    0.940    1.005

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.890 0.0153 18    0.858    0.922
 SS    0.879 0.0153 18    0.847    0.911

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS  -0.00332 0.0216 18  -0.154  0.8795

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS  -0.05195 0.0216 18  -2.402  0.0273

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS   0.01057 0.0216 18   0.489  0.6308
##Save p-values

#Genotypes within Sites
Tol_ScoreTP_M4_lm.geno<-data.frame(emmeans(Tol_ScoreTP_M4_lm, pairwise~Genotype | Site)$contrasts)
Tol_ScoreTP_M4_lm.geno<-Tol_ScoreTP_M4_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreTP_M4_lm.geno$group1<-paste(Tol_ScoreTP_M4_lm.geno$Site, Tol_ScoreTP_M4_lm.geno$group1, sep="_")
Tol_ScoreTP_M4_lm.geno$group2<-paste(Tol_ScoreTP_M4_lm.geno$Site, Tol_ScoreTP_M4_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_ScoreTP_M4_lm.site<-data.frame(emmeans(Tol_ScoreTP_M4_lm, pairwise~Site | Genotype)$contrasts)
Tol_ScoreTP_M4_lm.site<-Tol_ScoreTP_M4_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreTP_M4_lm.site$group1<-paste(Tol_ScoreTP_M4_lm.site$group1, Tol_ScoreTP_M4_lm.site$Genotype, sep="_")
Tol_ScoreTP_M4_lm.site$group2<-paste(Tol_ScoreTP_M4_lm.site$group2, Tol_ScoreTP_M4_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_ScoreTP_M4_lm.p<-rbind(Tol_ScoreTP_M4_lm.geno[,c(1:2,4:8)], Tol_ScoreTP_M4_lm.site[,c(1:2,4:8)])
Tol_ScoreTP_M4_lm.p<-Tol_ScoreTP_M4_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_ScoreTP_M4_lm.p$Sig<-ifelse(Tol_ScoreTP_M4_lm.p$p<0.001, "***", ifelse(Tol_ScoreTP_M4_lm.p$p<0.01, "**", ifelse(Tol_ScoreTP_M4_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_ScoreTP_M4_lm.p$Response<-rep("Color_TP", nrow(Tol_ScoreTP_M4_lm.p))
Tol_ScoreTP_M4_lm.p$TimeP<-rep("M4", nrow(Tol_ScoreTP_M4_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_ScoreTP_M4_SG<-summarySE(TolData_M4, measurevar="Score_TP.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_ScoreTP_M4_SG.plot<-ggplot(Tol_ScoreTP_M4_SG, aes(x=Site.Geno, y=Score_TP.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_TP.prop-se, ymax=Score_TP.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
   ggtitle("Color Retention by Timepoint")+
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Retained")+
  ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreTP_M4_lm.p,  y.position=1.1, step.increase=0.4, label="Sig", hide.ns=TRUE); Tol_ScoreTP_M4_SG.plot

Contrasts Across Metrics

Combine Contrast Results

Creating a heatmap to compare the direction and significance of pairwise comparisons across Tolerance metrics. Positive estimates indicate that Group 1 > Group 2. P values of less than 0.05 are considered significant.

##Combine Results
Tol_contrasts<-rbind(Tol_Chl_W2_lm.p, Tol_Chl_M1_lm.p, Tol_Chl_M4_lm.p, 
                     Tol_Sym_W2_lm.p, Tol_Sym_M1_lm.p, Tol_Sym_M4_lm.p, 
                     Tol_ScoreF_W2_lm.p, Tol_ScoreF_M1_lm.p, Tol_ScoreF_M4_lm.p, 
                     Tol_ScoreTP_W2_lm.p, Tol_ScoreTP_M1_lm.p, Tol_ScoreTP_M4_lm.p)

##Create Contrast Column
Tol_contrasts$Contrast<-paste(Tol_contrasts$group1, Tol_contrasts$group2, sep=" v. ")

##Add Set column with Contrast and Timepoint
Tol_contrasts$Set<-paste(Tol_contrasts$TimeP, Tol_contrasts$Contrast, sep=" ")

##Re-order by Seasonal Timepoint
Tol_contrasts$TimeP<-factor(Tol_contrasts$TimeP, levels=c("W2", "M1", "M4"), ordered=TRUE)
Tol_contrasts<- Tol_contrasts %>% arrange(desc(as.numeric(TimeP)))

Tol_contrasts$Set<-factor(Tol_contrasts$Set, levels=c(unique(Tol_contrasts$Set)), ordered=TRUE)

Standardize Response Scale

Convert Estimate to the Response scale (instead of log +1 scale) for models where the response was log transformed

Tol_contrasts$Estimate<-Tol_contrasts$estimate

#Chl M4
Tol_contrasts$Estimate[which(Tol_contrasts$Response=="Chlorophyll" & Tol_contrasts$TimeP=="M4")]<-c(exp(Tol_contrasts$estimate[which(Tol_contrasts$Response=="Chlorophyll" & Tol_contrasts$TimeP=="M4")])-1)

#Sym M1
Tol_contrasts$Estimate[which(Tol_contrasts$Response=="Symbionts" & Tol_contrasts$TimeP=="M1")]<-c(exp(Tol_contrasts$estimate[which(Tol_contrasts$Response=="Symbionts" & Tol_contrasts$TimeP=="M1")])-1)

Contrast Heatmaps

Summer 1 Timepoint W2

Tol_Pairs_W2.plot<-ggplot(data=Tol_contrasts[which(Tol_contrasts$TimeP=="W2"),], aes(x=Response, y=Contrast, fill=Estimate))+
  geom_tile()+
  geom_text(aes(label=Sig), size=sig.sz)+
  scale_fill_gradient2(low="#BA1E02FF", mid="white", high="#3BA0FDFF")+
  theme_bw()+
  ggtitle("Pairwise Contrasts Summer 1")+
  theme(axis.text.x=element_text(size=axis.title.sz, colour="black", angle=45, hjust=1),
        axis.text.y=element_text(size=axis.txt.sz-1, colour="black"),
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="", fill="Estimate");Tol_Pairs_W2.plot

Summer 2 Timepoint M1

Tol_Pairs_M1.plot<-ggplot(data=Tol_contrasts[which(Tol_contrasts$TimeP=="M1"),], aes(x=Response, y=Contrast, fill=Estimate))+
  geom_tile()+
  geom_text(aes(label=Sig), size=sig.sz)+
  scale_fill_gradient2(low="#BA1E02FF", mid="white", high="#3BA0FDFF")+
  theme_bw()+
  ggtitle("Pairwise Contrasts Summer 2")+
  theme(axis.text.x=element_text(size=axis.title.sz, colour="black", angle=45, hjust=1),
        axis.text.y=element_text(size=axis.txt.sz-1, colour="black"),
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="", fill="Estimate");Tol_Pairs_M1.plot

Winter Timepoint M4

Tol_Pairs_M4.plot<-ggplot(data=Tol_contrasts[which(Tol_contrasts$TimeP=="M4"),], aes(x=Response, y=Contrast, fill=Estimate))+
  geom_tile()+
  geom_text(aes(label=Sig), size=sig.sz)+
  scale_fill_gradient2(low="#BA1E02FF", mid="white", high="#3BA0FDFF")+
  theme_bw()+
  ggtitle("Pairwise Contrasts Month 4")+
  theme(axis.text.x=element_text(size=axis.title.sz, colour="black", angle=45, hjust=1),
        axis.text.y=element_text(size=axis.txt.sz-1, colour="black"),
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="", fill="Estimate");Tol_Pairs_M4.plot

All Timepoints

Tol_Pairs.plot<-ggplot(data=Tol_contrasts, aes(x=Response, y=Set, fill=Estimate))+
  geom_tile()+
  geom_text(aes(label=Sig), size=sig.sz)+
  scale_fill_gradient2(low="#BA1E02FF", mid="white", high="#3BA0FDFF")+
  theme_bw()+
  ggtitle("Pairwise Contrasts")+
  theme(axis.text.x=element_text(size=axis.title.sz, colour="black", angle=45, hjust=1),
        axis.text.y=element_text(size=axis.txt.sz-1, colour="black"),
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="", fill="Estimate");Tol_Pairs.plot

Significant Differences

Subsetting Contrasts to only include contrasts with significant differences in at least one of the thermal tolerance metrics (Chlorophyll or Symbiont or Color retention)

##Remove rows with non-significant p-values
Tol_contrasts_sig<-subset(Tol_contrasts, p < 0.05)

##Keep Sets where at least one metric shows a significant difference
Tol_Sets_sig<-data.frame(Set=c(unique(Tol_contrasts_sig$Set)))
Tol_contrasts_sig_Set<-merge(Tol_Sets_sig, Tol_contrasts, all.x=TRUE, all.y=FALSE)
Tol_Pairs_sig.plot<-ggplot(data=Tol_contrasts_sig_Set, aes(x=Response, y=Set, fill=Estimate))+
  geom_tile()+
  geom_text(aes(label=Sig), size=sig.sz)+
  scale_fill_gradient2(low="#BA1E02FF", mid="white", high="#3BA0FDFF")+
  theme_bw()+
  ggtitle("Significant Pairwise Contrasts")+
  theme(axis.text.x=element_text(size=axis.title.sz, colour="black", angle=45, hjust=1),
        axis.text.y=element_text(size=axis.txt.sz-1, colour="black"),
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="", fill="Estimate");Tol_Pairs_sig.plot

Figures

Figure S2 Tolerance Across Metrics

##Create Panel
Tolerance_fig<-plot_grid(Tol_Chl_W2_SG.plot, Tol_Chl_M1_SG.plot, Tol_Chl_M4_SG.plot,
                  Tol_ScoreF_W2_SG.plot, Tol_ScoreF_M1_SG.plot, Tol_ScoreF_M4_SG.plot,
                  Tol_ScoreTP_W2_SG.plot, Tol_ScoreTP_M1_SG.plot, Tol_ScoreTP_M4_SG.plot,
                  Tol_Sym_W2_SG.plot, Tol_Sym_M1_SG.plot, Tol_Sym_M4_SG.plot,
                        nrow=4, ncol=3, 
                        rel_widths=1,
                        rel_heights=1, 
                        labels=c("A", "B", "C", 
                                 "D", "E", "F", 
                                 "G", "H", "I", 
                                 "J", "K", "L"), 
                        label_size=panel.lab.sz, 
                        label_fontface = "bold")

##Save Figure
ggsave(filename="Figures/FigureS2_Tolerance_Across_Metrics.png", plot=Tolerance_fig, dpi=300, width=18, height=24, units="in")

Figure 3 Contrasts Heatmap

##Save Figure
ggsave(filename="Figures/Figure3_Tolerance_Heatmap.png", plot=Tol_Pairs.plot, dpi=300, width=8, height=12, units="in")

Tables

Linear Model Results

##Combine Results Tables
TableS2_Tol.lm.res<-rbind(Tol_Chl_W2_lm.res, Tol_Chl_M1_lm.res, Tol_Chl_M4_lm.res,
                        Tol_Sym_W2_lm.res, Tol_Sym_M1_lm.res, Tol_Sym_M4_lm.res,
                        Tol_ScoreF_W2_lm.res, Tol_ScoreF_M1_lm.res, Tol_ScoreF_M4_lm.res,
                    Tol_ScoreTP_W2_lm.res, Tol_ScoreTP_M1_lm.res, Tol_ScoreTP_M4_lm.res)

##Organize
names(TableS2_Tol.lm.res)
[1] "DF"        "Sum.Sq"    "Mean.Sq"   "F.value"   "p.value"   "Predictor"
[7] "EtaSq"     "Response"  "TimeP"    
TableS2_Tol.lm.res<-TableS2_Tol.lm.res[,c("TimeP", "Response", "Predictor", "DF", "Sum.Sq", "Mean.Sq", "F.value", "p.value", "EtaSq")]

#Round to 4 digits
TableS2_Tol.lm.res$Sum.Sq<-round(TableS2_Tol.lm.res$Sum.Sq, 4)
TableS2_Tol.lm.res$Mean.Sq<-round(TableS2_Tol.lm.res$Mean.Sq, 4)
TableS2_Tol.lm.res$F.value<-round(TableS2_Tol.lm.res$F.value, 4)
TableS2_Tol.lm.res$p.value<-round(TableS2_Tol.lm.res$p.value, 4)
TableS2_Tol.lm.res$EtaSq<-round(TableS2_Tol.lm.res$EtaSq, 4)

##Write Out Table
write.csv(TableS2_Tol.lm.res, "Tables/TableS2_Tolerance_LM_Results.csv", row.names=FALSE)

Pairwise Comparison Results

##Pairwise Results Table
TableS3_Tol.pairwise<-Tol_contrasts

##Organize
names(TableS3_Tol.pairwise)
 [1] "group1"   "group2"   "estimate" "SE"       "df"       "t.ratio"  "p"       
 [8] "Sig"      "Response" "TimeP"    "Contrast" "Set"      "Estimate"
TableS3_Tol.pairwise<-TableS3_Tol.pairwise[,c("TimeP", "Response", "Contrast", "Estimate", "SE", "df", "t.ratio", "p")]
TableS3_Tol.pairwise<-TableS3_Tol.pairwise %>% dplyr::rename( DF = df) %>% dplyr::rename( p.value = p)

#Round to 4 digits
TableS3_Tol.pairwise$Estimate<-round(TableS3_Tol.pairwise$Estimate, 4)
TableS3_Tol.pairwise$SE<-round(TableS3_Tol.pairwise$SE, 4)
TableS3_Tol.pairwise$t.ratio<-round(TableS3_Tol.pairwise$t.ratio, 4)
TableS3_Tol.pairwise$p.value<-round(TableS3_Tol.pairwise$p.value, 4)

##Write Out Table
write.csv(TableS3_Tol.pairwise, "Tables/TableS3_Tolerance_Pairwise_Results.csv", row.names=FALSE)
LS0tDQp0aXRsZTogIlRoZXJtYWwgVG9sZXJhbmNlIHdpdGggQ29sb3IgU2NvcmUgYW5kIEJsZWFjaGluZyBNZXRyaWNzIg0KYXV0aG9yOiAiU2VyZW5hIEhhY2tlcm90dCBhbmQgTGF1cmVuIEdyZWdvcnkiDQpkYXRlOiAiNy8xOS8yMDI0Ig0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQogICAgZGZfcHJpbnQ6IHBhZ2VkDQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KLS0tDQoNCiMgU2V0dXANCmBgYHtyIFNldHVwLCBpbmNsdWRlID0gRkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFKQ0KYGBgDQoNCg0KIyMjIExvYWQgUGFja2FnZXMNCmBgYHtyfQ0KIyNJbnN0YWxsIFBhY2thZ2VzIGlmIE5lZWRlZA0KaWYgKCFyZXF1aXJlKCJnZ3Bsb3QyIikpIGluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQ0KaWYgKCFyZXF1aXJlKCJlZmZlY3RzaXplIikpIGluc3RhbGwucGFja2FnZXMoImVmZmVjdHNpemUiKQ0KaWYgKCFyZXF1aXJlKCJlbW1lYW5zIikpIGluc3RhbGwucGFja2FnZXMoImVtbWVhbnMiKQ0KaWYgKCFyZXF1aXJlKCJkcGx5ciIpKSBpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIpDQppZiAoIXJlcXVpcmUoInRpZHlyIikpIGluc3RhbGwucGFja2FnZXMoInRpZHlyIikNCmlmICghcmVxdWlyZSgiUm1pc2MiKSkgaW5zdGFsbC5wYWNrYWdlcygiUm1pc2MiKQ0KaWYgKCFyZXF1aXJlKCJnZ3B1YnIiKSkgaW5zdGFsbC5wYWNrYWdlcygiZ2dwdWJyIikNCmlmICghcmVxdWlyZSgiY293cGxvdCIpKSBpbnN0YWxsLnBhY2thZ2VzKCJjb3dwbG90IikNCmlmICghcmVxdWlyZSgiZ3JpZEdyYXBoaWNzIikpIGluc3RhbGwucGFja2FnZXMoImdyaWRHcmFwaGljcyIpDQppZiAoIXJlcXVpcmUoInRpZHlyIikpIGluc3RhbGwucGFja2FnZXMoInRpZHlyIikNCg0KIyNMb2FkIFBhY2thZ2VzDQpsaWJyYXJ5KGdncGxvdDIpICNSZXF1aXJlZCBmb3IgcGxvdHRpbmcNCmxpYnJhcnkoZWZmZWN0c2l6ZSkgI1JlcXVpcmVkIGZvciBldGFfc3F1YXJlZCBlZmZlY3Qgc2l6ZXMNCmxpYnJhcnkoZW1tZWFucykgI1JlcXVpcmVkIGZvciBwYWlyd2lzZSBjb21wYXJpc29ucw0KbGlicmFyeShkcGx5cikgI1JlcXVpcmVkIHRvIHNlcGVyYXRlIGNvbHVtbnMgaW4gZGF0YWZyYW1lDQpsaWJyYXJ5KHRpZHlyKSAjUmVxdWlyZWQgZm9yIGRhdGEgb3JnYW5pemF0aW9uDQpsaWJyYXJ5KFJtaXNjKSAjUmVxdWlyZWQgZm9yIHN1bW1hcnlTRSBmb3Igc3VtbWFyeSBzdGF0aXN0aWNzDQpsaWJyYXJ5KGdncHVicikgI1JlcXVpcmVkIGZvciBhZGRpbmcgcGFpcndpc2UgcC12YWx1ZXMgdG8gcGxvdHMgd2l0aCBzdGF0X3B2YWx1ZV9tYW51YWwgDQpsaWJyYXJ5KGNvd3Bsb3QpICNSZXF1aXJlZCBmb3IgYXJyYW5naW5nIGdncGxvdHMgDQpsaWJyYXJ5KGdyaWRHcmFwaGljcykgI1JlcXVpcmVkIGZvciBhZGRpbmcgbGFiZWxzIHRvIGFycmFuZ2VkIHBsb3RzDQpsaWJyYXJ5KHRpZHlyKSAjUmVxdWlyZWQgZm9yIHJlc2hhcGluZyBkYXRhZnJvbSBmcm9tIGEgd2lkZSB0byBsb25nIGZvcm1hdC4NCmBgYA0KTm90ZTogUnVuICJHcmFwaGluZyBQYXJhbWV0ZXJzIiBzZWN0aW9uIGZyb20gMDFfRXhwZXJpbWVudGFsU2V0dXAuUiBmaWxlDQoNCg0KIyMjIExvYWQgYW5kIE9yZ2FuaXplIERhdGENCk5vdGU6IEZ1bGwgRGF0YSB3aXRoIEJsZWFjaGluZyBNZXRyaWNzIGFuZCBDb2xvciBTY29yZXMgY3JlYXRlZCBpbiAwNF9Nb2RlbHMuUiBmaWxlDQpgYGB7cn0NCiNMb2FkIERhdGENCkZ1bGxEYXRhPC1yZWFkLmNzdigiT3V0cHV0cy9GdWxsRGF0YS5jc3YiLCBoZWFkZXI9VFJVRSkNCg0KDQojU2V0IGZhY3RvciB2YXJpYWJsZXMgDQpGdWxsRGF0YSRUaW1lUDwtZmFjdG9yKEZ1bGxEYXRhJFRpbWVQLCBsZXZlbHM9YygiVzIiLCAiTTEiLCAiTTQiKSwgb3JkZXJlZD1UUlVFKQ0KRnVsbERhdGEkU2l0ZTwtZmFjdG9yKEZ1bGxEYXRhJFNpdGUsIGxldmVscz1jKCJLTCIsICJTUyIpLCBvcmRlcmVkPVRSVUUpDQpGdWxsRGF0YSRHZW5vdHlwZTwtZmFjdG9yKEZ1bGxEYXRhJEdlbm90eXBlLCBsZXZlbHM9YygiQUMxMCIsICJBQzEyIiwgIkFDOCIpLCBvcmRlcmVkPVRSVUUpDQpGdWxsRGF0YSRUcmVhdG1lbnQ8LWZhY3RvcihGdWxsRGF0YSRUcmVhdG1lbnQsIGxldmVscz1jKCJDb250cm9sIiwgIkhlYXQiKSwgb3JkZXJlZD1UUlVFKQ0KRnVsbERhdGEkVHJlYXQ8LWZhY3RvcihGdWxsRGF0YSRUcmVhdCwgbGV2ZWxzPWMoIkMiLCAiSCIpLCBvcmRlcmVkPVRSVUUpDQpGdWxsRGF0YSRTZWFzPC1mYWN0b3IoRnVsbERhdGEkU2VhcywgbGV2ZWxzPWMoIlN1bW1lcjEiLCAiU3VtbWVyMiIsICJXaW50ZXIiKSwgb3JkZXJlZD1UUlVFKQ0KYGBgDQoNCg0KIyBQZXJjZW50IFJldGVudGlvbg0KDQojIyMgU3Vic2V0IFRoZXJtYWwgQXNzYXkgRGF0YSBieSBUcmVhdG1lbnQNCmBgYHtyfQ0KIyNDb250cm9sDQpGdWxsRGF0YV9DPC1zdWJzZXQoRnVsbERhdGEsIFRyZWF0PT0iQyIpDQoNCiMjSGVhdGVkDQpGdWxsRGF0YV9IPC1zdWJzZXQoRnVsbERhdGEsIFRyZWF0PT0iSCIpDQpgYGANCg0KDQojIyMgQ2FsY3VsYXRlIFBlcmNlbnQgUmV0ZW50aW9uDQpDYWxjdWxhdGluZyByZXRlbnRpb24gYXMgcHJvcG9ydGlvbiByZW1haW5pbmcgcmVsYXRpdmUgdG8gY29ycmVzcG9uZGluZyBjb250cm9sIGxldmVscyAoMC0xKSBmb3IgZWFjaCBzaXRlIGFuZCBnZW5vdHlwZSBhdCBlYWNoIHRpbWVwb2ludC4NCmBgYHtyfQ0KIyNDYWxjdWxhdGUgYXZlcmFnZXMgZm9yIENvbnRyb2wgVHJlYXRtZW50IGZvciBlYWNoIFNpdGUsIEdlbm90eXBlLCBUaW1lcG9pbnQsIGFuZCBTZWFzb24NCm5hbWVzKEZ1bGxEYXRhX0MpDQpGdWxsRGF0YV9DLmE8LWFnZ3JlZ2F0ZShGdWxsRGF0YV9DWyxjKDEwOjExLCAxMzoxNCldLCBsaXN0KEZ1bGxEYXRhX0MkU2l0ZSwgRnVsbERhdGFfQyRHZW5vdHlwZSwgRnVsbERhdGFfQyRUaW1lUCwgRnVsbERhdGFfQyRTZWFzKSwgbWVhbiwgbmEuYWN0aW9uID0gbmEub21pdCkNCm5hbWVzKEZ1bGxEYXRhX0MuYSlbMTo0XTwtYygiU2l0ZSIsICJHZW5vdHlwZSIsICJUaW1lUCIsICJTZWFzIikNCm5hbWVzKEZ1bGxEYXRhX0MuYSlbNTo4XTwtcGFzdGUobmFtZXMoRnVsbERhdGFfQylbYygxMDoxMSwgMTM6MTQpXSwgIkMiLCBzZXA9Il8iKQ0KDQojI01lcmdlIENvbnRyb2wgQXZlcmFnZXMgd2l0aCBIZWF0ZWQgU2FtcGxlcw0KI01lcmdlcyBieSBTaXRlLCBHZW5vdHlwZSwgVGltZXBvaW50LCBhbmQgU2Vhc29uDQpUb2xEYXRhPC1tZXJnZShGdWxsRGF0YV9ILCBGdWxsRGF0YV9DLmEsIGFsbC54PVRSVUUgKQ0KDQojI0NhbGN1bGF0ZSBQcm9wb3J0aW9uIFJldGFpbmVkIGZvciBlYWNoIEJsZWFjaGluZyBNZXRyaWMgcmVsYXRpdmUgdG8gQ29udHJvbA0KVG9sRGF0YSRTY29yZV9GdWxsLnByb3A8LXJvdW5kKChUb2xEYXRhJFNjb3JlX0Z1bGwvVG9sRGF0YSRTY29yZV9GdWxsX0MpLCA0KQ0KVG9sRGF0YSRTY29yZV9UUC5wcm9wPC1yb3VuZCgoVG9sRGF0YSRTY29yZV9UUC9Ub2xEYXRhJFNjb3JlX1RQX0MpLCA0KQ0KVG9sRGF0YSRDaGwucHJvcDwtcm91bmQoKFRvbERhdGEkQ2hsX3VnLmNtMi9Ub2xEYXRhJENobF91Zy5jbTJfQyksIDQpDQpUb2xEYXRhJFN5bS5wcm9wPC1yb3VuZCgoVG9sRGF0YSRTeW0xMC42X2NtMi9Ub2xEYXRhJFN5bTEwLjZfY20yX0MpLCA0KQ0KDQojI1NldCB2YWx1ZXMgPjEgdG8gMQ0KVG9sRGF0YSRTY29yZV9GdWxsLnByb3Bbd2hpY2goVG9sRGF0YSRTY29yZV9GdWxsLnByb3A+MSldPC0xLjAwMDANClRvbERhdGEkU2NvcmVfVFAucHJvcFt3aGljaChUb2xEYXRhJFNjb3JlX1RQLnByb3A+MSldPC0xLjAwMDANClRvbERhdGEkQ2hsLnByb3Bbd2hpY2goVG9sRGF0YSRDaGwucHJvcD4xKV08LTEuMDAwMA0KVG9sRGF0YSRTeW0ucHJvcFt3aGljaChUb2xEYXRhJFN5bS5wcm9wPjEpXTwtMS4wMDAwDQoNCiMjQ3JlYXRlIFNpdGUgYW5kIEdlbm90eXBlIFZhcmlhYmxlDQpUb2xEYXRhJFNpdGUuR2VubzwtcGFzdGUoVG9sRGF0YSRTaXRlLCBUb2xEYXRhJEdlbm90eXBlLCBzZXA9Il8iKQ0KYGBgDQoNCg0KIyMjIFN1YnNldCBieSBUaW1lcG9pbnQNCmBgYHtyfQ0KVG9sRGF0YV9XMjwtc3Vic2V0KFRvbERhdGEsIFRpbWVQPT0iVzIiKQ0KVG9sRGF0YV9NMTwtc3Vic2V0KFRvbERhdGEsIFRpbWVQPT0iTTEiKQ0KVG9sRGF0YV9NNDwtc3Vic2V0KFRvbERhdGEsIFRpbWVQPT0iTTQiKQ0KYGBgDQoNCg0KDQojIFRoZXJtYWwgVG9sZXJhbmNlIENobG9yb3BoeWxsDQoNCiMjIEZ1bGwgU2V0DQoNCiMjIyBSdW4gTW9kZWwNCmBgYHtyfQ0KIyNDaGVjayBub3JtYWxpdHkNCmhpc3QoVG9sRGF0YSRDaGwucHJvcCkNCnNoYXBpcm8udGVzdChUb2xEYXRhJENobC5wcm9wKQ0KI05vcm1hbA0KDQojI01vZGVsIGFzIGEgZnVuY3Rpb24gb2YgU2l0ZSBhbmQgR2Vub3R5cGUgYW5kIFRpbWVwb2ludA0KVG9sX0NobF9sbTwtbG0oQ2hsLnByb3B+U2l0ZStHZW5vdHlwZStUaW1lUCsgU2l0ZTpHZW5vdHlwZSArIFNpdGU6VGltZVAgKyBHZW5vdHlwZTpUaW1lUCwgZGF0YT1Ub2xEYXRhKQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX0NobF9sbSkpKQ0KDQojUS1RIHBsb3QNCnFxbm9ybShyZXNpZChUb2xfQ2hsX2xtKSk7IHFxbGluZShyZXNpZChUb2xfQ2hsX2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9DaGxfbG0pLCByZXNpZChUb2xfQ2hsX2xtKSkNCg0KYGBgDQoNCg0KIyMjIE1vZGVsIFJlc3VsdHMNCg0KYGBge3J9DQojTW9kZWwgUmVzdWx0cw0Kc3VtbWFyeShUb2xfQ2hsX2xtKQ0KYW5vdmEoVG9sX0NobF9sbSkNCg0KI0VmZmVjdCBTaXplIG9mIFByZWRpY3RvcnMNCmV0YV9zcXVhcmVkKFRvbF9DaGxfbG0sIHBhcnRpYWw9RkFMU0UpDQoNCiMjU2F2ZSBtb2RlbCByZXN1bHRzDQpUb2xfQ2hsX2xtLnJlczwtZGF0YS5mcmFtZShhbm92YShUb2xfQ2hsX2xtKSkNClRvbF9DaGxfbG0ucmVzJFByZWRpY3Rvcjwtcm93bmFtZXMoVG9sX0NobF9sbS5yZXMpDQpUb2xfQ2hsX2xtLnJlcyRFdGFTcTwtYyhldGFfc3F1YXJlZChUb2xfQ2hsX2xtLCBwYXJ0aWFsPUZBTFNFKSRFdGEyLCBOQSkNClRvbF9DaGxfbG0ucmVzJFJlc3BvbnNlPC1yZXAoIkNobG9yb3BoeWxsIiwgbnJvdyhUb2xfQ2hsX2xtLnJlcykpDQpUb2xfQ2hsX2xtLnJlczwtVG9sX0NobF9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KU3Ryb25nIGluZmx1ZW5jZSBvZiBUaW1lcG9pbnQsIGluY2x1ZGluZyBpbnRlcmFjdGlvbnMgd2l0aCBtYWluIHZhcmlhYmxlcyBvZiBpbnRlcmVzdCwgU2l0ZSBhbmQgR2Vub3R5cGUuIFdpbGwgYW5hbHl6ZSBlYWNoIFRpbWVwb2ludCBpbmRpdmlkdWFsbHkuIA0KDQoNCiMjIENobCBTdW1tZXIgMSBUaW1lcG9pbnQgVzIgDQoNCiMjIyBSdW4gTW9kZWwNCmBgYHtyfQ0KIyNDaGVjayBub3JtYWxpdHkNCmhpc3QoVG9sRGF0YV9XMiRDaGwucHJvcCkNCnNoYXBpcm8udGVzdChUb2xEYXRhX1cyJENobC5wcm9wKQ0KI05vcm1hbA0KDQojI01vZGVsIGFzIGEgZnVuY3Rpb24gb2YgU2l0ZSBhbmQgR2Vub3R5cGUNClRvbF9DaGxfVzJfbG08LWxtKENobC5wcm9wflNpdGUrR2Vub3R5cGUrU2l0ZTpHZW5vdHlwZSwgZGF0YT1Ub2xEYXRhX1cyKQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX0NobF9XMl9sbSkpKQ0KDQojUS1RIHBsb3QNCnFxbm9ybShyZXNpZChUb2xfQ2hsX1cyX2xtKSk7IHFxbGluZShyZXNpZChUb2xfQ2hsX1cyX2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9DaGxfVzJfbG0pLCByZXNpZChUb2xfQ2hsX1cyX2xtKSkNCg0KYGBgDQoNCg0KIyMjIE1vZGVsIFJlc3VsdHMNCg0KIyMjIyBPdmVyYWxsDQpgYGB7cn0NCiNNb2RlbCBSZXN1bHRzDQpzdW1tYXJ5KFRvbF9DaGxfVzJfbG0pDQphbm92YShUb2xfQ2hsX1cyX2xtKQ0KDQojRWZmZWN0IFNpemUgb2YgUHJlZGljdG9ycw0KZXRhX3NxdWFyZWQoVG9sX0NobF9XMl9sbSwgcGFydGlhbD1GQUxTRSkNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9DaGxfVzJfbG0ucmVzPC1kYXRhLmZyYW1lKGFub3ZhKFRvbF9DaGxfVzJfbG0pKQ0KVG9sX0NobF9XMl9sbS5yZXMkUHJlZGljdG9yPC1yb3duYW1lcyhUb2xfQ2hsX1cyX2xtLnJlcykNClRvbF9DaGxfVzJfbG0ucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9DaGxfVzJfbG0sIHBhcnRpYWw9RkFMU0UpJEV0YTIsIE5BKQ0KVG9sX0NobF9XMl9sbS5yZXMkUmVzcG9uc2U8LXJlcCgiQ2hsb3JvcGh5bGwiLCBucm93KFRvbF9DaGxfVzJfbG0ucmVzKSkNClRvbF9DaGxfVzJfbG0ucmVzJFRpbWVQPC1yZXAoIlcyIiwgbnJvdyhUb2xfQ2hsX1cyX2xtLnJlcykpDQpUb2xfQ2hsX1cyX2xtLnJlczwtVG9sX0NobF9XMl9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KDQpTaWduaWZpY2FudCBlZmZlY3Qgb2YgR2Vub3R5cGUuIFN0aWxsIGNoZWNraW5nIFNpdGUqR2Vub3R5cGUgZm9yIGNvbXBhcmFiaWxpdHkgYWNyb3NzIFRpbWVwb2ludHMuDQoNCg0KIyMjIyBQYWlyd2lzZQ0KYGBge3J9DQojUGFpcndpc2UgY29tcGFyaXNvbnMgYWNyb3NzOg0KDQojR2Vub3R5cGVzIHdpdGhpbiBTaXRlcw0KZW1tZWFucyhUb2xfQ2hsX1cyX2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQplbW1lYW5zKFRvbF9DaGxfVzJfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkNCg0KIyNTYXZlIHAtdmFsdWVzDQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQpUb2xfQ2hsX1cyX2xtLmdlbm88LWRhdGEuZnJhbWUoZW1tZWFucyhUb2xfQ2hsX1cyX2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpJGNvbnRyYXN0cykNClRvbF9DaGxfVzJfbG0uZ2VubzwtVG9sX0NobF9XMl9sbS5nZW5vICU+JSBzZXBhcmF0ZShjb2w9Y29udHJhc3QsIGludG89YygiZ3JvdXAxIiwgImdyb3VwMiIpLCBzZXA9IiAtICIsIHJlbW92ZT1UUlVFKQ0KVG9sX0NobF9XMl9sbS5nZW5vJGdyb3VwMTwtcGFzdGUoVG9sX0NobF9XMl9sbS5nZW5vJFNpdGUsIFRvbF9DaGxfVzJfbG0uZ2VubyRncm91cDEsIHNlcD0iXyIpDQpUb2xfQ2hsX1cyX2xtLmdlbm8kZ3JvdXAyPC1wYXN0ZShUb2xfQ2hsX1cyX2xtLmdlbm8kU2l0ZSwgVG9sX0NobF9XMl9sbS5nZW5vJGdyb3VwMiwgc2VwPSJfIikNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNClRvbF9DaGxfVzJfbG0uc2l0ZTwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9DaGxfVzJfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkkY29udHJhc3RzKQ0KVG9sX0NobF9XMl9sbS5zaXRlPC1Ub2xfQ2hsX1cyX2xtLnNpdGUgJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfQ2hsX1cyX2xtLnNpdGUkZ3JvdXAxPC1wYXN0ZShUb2xfQ2hsX1cyX2xtLnNpdGUkZ3JvdXAxLCBUb2xfQ2hsX1cyX2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQpUb2xfQ2hsX1cyX2xtLnNpdGUkZ3JvdXAyPC1wYXN0ZShUb2xfQ2hsX1cyX2xtLnNpdGUkZ3JvdXAyLCBUb2xfQ2hsX1cyX2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQoNCiNGdWxsIGxpc3Qgb2YgcC12YWx1ZXMNClRvbF9DaGxfVzJfbG0ucDwtcmJpbmQoVG9sX0NobF9XMl9sbS5nZW5vWyxjKDE6Miw0OjgpXSwgVG9sX0NobF9XMl9sbS5zaXRlWyxjKDE6Miw0OjgpXSkNClRvbF9DaGxfVzJfbG0ucDwtVG9sX0NobF9XMl9sbS5wICU+JSBkcGx5cjo6cmVuYW1lKCBwID0gcC52YWx1ZSkNCg0KI0FkZCBTaWduaWZpY2FuY2UgTGV2ZWxzDQpUb2xfQ2hsX1cyX2xtLnAkU2lnPC1pZmVsc2UoVG9sX0NobF9XMl9sbS5wJHA8MC4wMDEsICIqKioiLCBpZmVsc2UoVG9sX0NobF9XMl9sbS5wJHA8MC4wMSwgIioqIiwgaWZlbHNlKFRvbF9DaGxfVzJfbG0ucCRwPDAuMDUsICIqIiwgTkEpKSkNCg0KI1NwZWNpZnkgUmVzcG9uc2UgYW5kIFRpbWVwb2ludA0KVG9sX0NobF9XMl9sbS5wJFJlc3BvbnNlPC1yZXAoIkNobG9yb3BoeWxsIiwgbnJvdyhUb2xfQ2hsX1cyX2xtLnApKQ0KVG9sX0NobF9XMl9sbS5wJFRpbWVQPC1yZXAoIlcyIiwgbnJvdyhUb2xfQ2hsX1cyX2xtLnApKQ0KDQpgYGANCg0KDQojIyMgUGxvdCBSZXRlbnRpb24gYnkgU2l0ZSBhbmQgR2Vub3R5cGUNCmBgYHtyfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgR2Vub3R5cGUNClRvbF9DaGxfVzJfU0c8LXN1bW1hcnlTRShUb2xEYXRhX1cyLCBtZWFzdXJldmFyPSJDaGwucHJvcCIsIGdyb3VwdmFycz1jKCJTaXRlLkdlbm8iLCAiU2l0ZSIsICJHZW5vdHlwZSIpLCBuYS5ybT1UUlVFKQ0KDQojI1Bsb3QgQXZlcmFnZSBSZXRlbnRpb24gYWNyb3NzIFRyZWF0bWVudHMNClRvbF9DaGxfVzJfU0cucGxvdDwtZ2dwbG90KFRvbF9DaGxfVzJfU0csIGFlcyh4PVNpdGUuR2VubywgeT1DaGwucHJvcCwgY29sb3VyPUdlbm90eXBlKSkgKyANCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1DaGwucHJvcC1zZSwgeW1heD1DaGwucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeikrDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeikrIA0KICAgZ2d0aXRsZSgiQ2hsb3JvcGh5bGwgUmV0ZW50aW9uIikrDQogIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCANCiAgICAgICAgbGVnZW5kLmRpcmVjdGlvbj0iaG9yaXpvbnRhbCIsDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IlByb3BvcnRpb24gUmV0YWluZWQiKSsNCiAgeWxpbSgwLCAxKSsgDQogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIiIsIktsZWluIiwiIiwiIiwiU29tZXRoaW5nIFNwZWNpYWwiLCIiKSkrDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBHZW5vLmNvbG9ycy5vKSsgDQogIHN0YXRfcHZhbHVlX21hbnVhbChkYXRhPVRvbF9DaGxfVzJfbG0ucCwgIHkucG9zaXRpb249MC40LCBzdGVwLmluY3JlYXNlPTAuMjUsIGxhYmVsPSJTaWciLCBoaWRlLm5zPVRSVUUpOyBUb2xfQ2hsX1cyX1NHLnBsb3QNCg0KYGBgDQoNCg0KIyMgQ2hsIFN1bW1lciAyIFRpbWVwb2ludCBNMQ0KDQojIyMgUnVuIE1vZGVsDQpgYGB7cn0NCiMjQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRvbERhdGFfTTEkQ2hsLnByb3ApDQpzaGFwaXJvLnRlc3QoVG9sRGF0YV9NMSRDaGwucHJvcCkNCiNOb3JtYWwNCg0KIyNNb2RlbCBhcyBhIGZ1bmN0aW9uIG9mIFNpdGUgYW5kIEdlbm90eXBlDQpUb2xfQ2hsX00xX2xtPC1sbShDaGwucHJvcH5TaXRlK0dlbm90eXBlK1NpdGU6R2Vub3R5cGUsIGRhdGE9VG9sRGF0YV9NMSkNCg0KYGBgDQoNCg0KIyMjIyBDaGVjayBSZXNpZHVhbHMNCmBgYHtyfQ0KIyNDaGVjayBOb3JtYWxpdHkgb2YgUmVzaWR1YWxzDQojRGlzdHJpYnV0aW9uIA0KcGxvdChkZW5zaXR5KHJlc2lkKFRvbF9DaGxfTTFfbG0pKSkNCg0KI1EtUSBwbG90DQpxcW5vcm0ocmVzaWQoVG9sX0NobF9NMV9sbSkpOyBxcWxpbmUocmVzaWQoVG9sX0NobF9NMV9sbSkpDQoNCiMjQ2hlY2sgVmFyaWFuY2Ugb2YgUmVzaWR1YWxzIGFjcm9zcyBGaXR0ZWQgVmFsdWVzDQpwbG90KGZpdHRlZChUb2xfQ2hsX00xX2xtKSwgcmVzaWQoVG9sX0NobF9NMV9sbSkpDQoNCmBgYA0KDQoNCiMjIyBNb2RlbCBSZXN1bHRzDQoNCiMjIyMgT3ZlcmFsbA0KYGBge3J9DQojTW9kZWwgUmVzdWx0cw0Kc3VtbWFyeShUb2xfQ2hsX00xX2xtKQ0KYW5vdmEoVG9sX0NobF9NMV9sbSkNCg0KI0VmZmVjdCBTaXplIG9mIFByZWRpY3RvcnMNCmV0YV9zcXVhcmVkKFRvbF9DaGxfTTFfbG0sIHBhcnRpYWw9RkFMU0UpDQoNCiMjU2F2ZSBtb2RlbCByZXN1bHRzDQpUb2xfQ2hsX00xX2xtLnJlczwtZGF0YS5mcmFtZShhbm92YShUb2xfQ2hsX00xX2xtKSkNClRvbF9DaGxfTTFfbG0ucmVzJFByZWRpY3Rvcjwtcm93bmFtZXMoVG9sX0NobF9NMV9sbS5yZXMpDQpUb2xfQ2hsX00xX2xtLnJlcyRFdGFTcTwtYyhldGFfc3F1YXJlZChUb2xfQ2hsX00xX2xtLCBwYXJ0aWFsPUZBTFNFKSRFdGEyLCBOQSkNClRvbF9DaGxfTTFfbG0ucmVzJFJlc3BvbnNlPC1yZXAoIkNobG9yb3BoeWxsIiwgbnJvdyhUb2xfQ2hsX00xX2xtLnJlcykpDQpUb2xfQ2hsX00xX2xtLnJlcyRUaW1lUDwtcmVwKCJNMSIsIG5yb3coVG9sX0NobF9NMV9sbS5yZXMpKQ0KVG9sX0NobF9NMV9sbS5yZXM8LVRvbF9DaGxfTTFfbG0ucmVzICU+JSBkcGx5cjo6cmVuYW1lKCBwLnZhbHVlID0gIlByLi5GLiIsIERGPSAiRGYiKQ0KDQpgYGANCg0KU2lnbmlmaWNhbnQgZWZmZWN0IG9mIEdlbm90eXBlLiBTdGlsbCBjaGVja2luZyBTaXRlKkdlbm90eXBlIGZvciBjb21wYXJhYmlsaXR5IGFjcm9zcyBUaW1lcG9pbnRzLg0KDQoNCiMjIyMgUGFpcndpc2UNCmBgYHtyfQ0KI1BhaXJ3aXNlIGNvbXBhcmlzb25zIGFjcm9zczoNCg0KI0dlbm90eXBlcyB3aXRoaW4gU2l0ZXMNCmVtbWVhbnMoVG9sX0NobF9NMV9sbSwgcGFpcndpc2V+R2Vub3R5cGUgfCBTaXRlKQ0KDQojU2l0ZXMgd2l0aGluIEdlbm90eXBlcw0KZW1tZWFucyhUb2xfQ2hsX00xX2xtLCBwYWlyd2lzZX5TaXRlIHwgR2Vub3R5cGUpDQoNCiMjU2F2ZSBwLXZhbHVlcw0KDQojR2Vub3R5cGVzIHdpdGhpbiBTaXRlcw0KVG9sX0NobF9NMV9sbS5nZW5vPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX0NobF9NMV9sbSwgcGFpcndpc2V+R2Vub3R5cGUgfCBTaXRlKSRjb250cmFzdHMpDQpUb2xfQ2hsX00xX2xtLmdlbm88LVRvbF9DaGxfTTFfbG0uZ2VubyAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9DaGxfTTFfbG0uZ2VubyRncm91cDE8LXBhc3RlKFRvbF9DaGxfTTFfbG0uZ2VubyRTaXRlLCBUb2xfQ2hsX00xX2xtLmdlbm8kZ3JvdXAxLCBzZXA9Il8iKQ0KVG9sX0NobF9NMV9sbS5nZW5vJGdyb3VwMjwtcGFzdGUoVG9sX0NobF9NMV9sbS5nZW5vJFNpdGUsIFRvbF9DaGxfTTFfbG0uZ2VubyRncm91cDIsIHNlcD0iXyIpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQpUb2xfQ2hsX00xX2xtLnNpdGU8LWRhdGEuZnJhbWUoZW1tZWFucyhUb2xfQ2hsX00xX2xtLCBwYWlyd2lzZX5TaXRlIHwgR2Vub3R5cGUpJGNvbnRyYXN0cykNClRvbF9DaGxfTTFfbG0uc2l0ZTwtVG9sX0NobF9NMV9sbS5zaXRlICU+JSBzZXBhcmF0ZShjb2w9Y29udHJhc3QsIGludG89YygiZ3JvdXAxIiwgImdyb3VwMiIpLCBzZXA9IiAtICIsIHJlbW92ZT1UUlVFKQ0KVG9sX0NobF9NMV9sbS5zaXRlJGdyb3VwMTwtcGFzdGUoVG9sX0NobF9NMV9sbS5zaXRlJGdyb3VwMSwgVG9sX0NobF9NMV9sbS5zaXRlJEdlbm90eXBlLCBzZXA9Il8iKQ0KVG9sX0NobF9NMV9sbS5zaXRlJGdyb3VwMjwtcGFzdGUoVG9sX0NobF9NMV9sbS5zaXRlJGdyb3VwMiwgVG9sX0NobF9NMV9sbS5zaXRlJEdlbm90eXBlLCBzZXA9Il8iKQ0KDQojRnVsbCBsaXN0IG9mIHAtdmFsdWVzDQpUb2xfQ2hsX00xX2xtLnA8LXJiaW5kKFRvbF9DaGxfTTFfbG0uZ2Vub1ssYygxOjIsNDo4KV0sIFRvbF9DaGxfTTFfbG0uc2l0ZVssYygxOjIsNDo4KV0pDQpUb2xfQ2hsX00xX2xtLnA8LVRvbF9DaGxfTTFfbG0ucCAlPiUgZHBseXI6OnJlbmFtZSggcCA9IHAudmFsdWUpDQoNCiNBZGQgU2lnbmlmaWNhbmNlIExldmVscw0KVG9sX0NobF9NMV9sbS5wJFNpZzwtaWZlbHNlKFRvbF9DaGxfTTFfbG0ucCRwPDAuMDAxLCAiKioqIiwgaWZlbHNlKFRvbF9DaGxfTTFfbG0ucCRwPDAuMDEsICIqKiIsIGlmZWxzZShUb2xfQ2hsX00xX2xtLnAkcDwwLjA1LCAiKiIsIE5BKSkpDQoNCiNTcGVjaWZ5IFJlc3BvbnNlIGFuZCBUaW1lcG9pbnQNClRvbF9DaGxfTTFfbG0ucCRSZXNwb25zZTwtcmVwKCJDaGxvcm9waHlsbCIsIG5yb3coVG9sX0NobF9NMV9sbS5wKSkNClRvbF9DaGxfTTFfbG0ucCRUaW1lUDwtcmVwKCJNMSIsIG5yb3coVG9sX0NobF9NMV9sbS5wKSkNCg0KYGBgDQoNCg0KIyMjIFBsb3QgUmV0ZW50aW9uIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpgYGB7cn0NCiMjU3VtbWFyeSBzdGF0aXN0aWNzIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpUb2xfQ2hsX00xX1NHPC1zdW1tYXJ5U0UoVG9sRGF0YV9NMSwgbWVhc3VyZXZhcj0iQ2hsLnByb3AiLCBncm91cHZhcnM9YygiU2l0ZS5HZW5vIiwgIlNpdGUiLCAiR2Vub3R5cGUiKSwgbmEucm09VFJVRSkNCg0KIyNQbG90IEF2ZXJhZ2UgUmV0ZW50aW9uIGFjcm9zcyBUcmVhdG1lbnRzDQpUb2xfQ2hsX00xX1NHLnBsb3Q8LWdncGxvdChUb2xfQ2hsX00xX1NHLCBhZXMoeD1TaXRlLkdlbm8sIHk9Q2hsLnByb3AsIGNvbG91cj1HZW5vdHlwZSkpICsgDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49Q2hsLnByb3Atc2UsIHltYXg9Q2hsLnByb3Arc2UpLCB3aWR0aD1jYXAuc3osIGxpbmV3aWR0aD1iYXIuc3opKw0KICBnZW9tX3BvaW50KHNpemU9cG9pbnQuc3opKyANCiAgIGdndGl0bGUoIkNobG9yb3BoeWxsIFJldGVudGlvbiIpKw0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKCBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksDQogICAgICAgIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIiksDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwgDQogICAgICAgIGxlZ2VuZC5kaXJlY3Rpb249Imhvcml6b250YWwiLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBwbG90LnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgaGp1c3QgPSAwLjUpKSsNCiAgbGFicyh4PSIiLCB5PSJQcm9wb3J0aW9uIFJldGFpbmVkIikrDQogIHlsaW0oMCwgMSkrIA0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIiLCJLbGVpbiIsIiIsIiIsIlNvbWV0aGluZyBTcGVjaWFsIiwiIikpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gR2Vuby5jb2xvcnMubykrIA0KICBzdGF0X3B2YWx1ZV9tYW51YWwoZGF0YT1Ub2xfQ2hsX00xX2xtLnAsICB5LnBvc2l0aW9uPTAuNCwgc3RlcC5pbmNyZWFzZT0wLjI1LCBsYWJlbD0iU2lnIiwgaGlkZS5ucz1UUlVFKTsgVG9sX0NobF9NMV9TRy5wbG90DQoNCmBgYA0KDQoNCiMjIENobCBXaW50ZXIgVGltZXBvaW50IE00DQoNCiMjIyBSdW4gTW9kZWwNCmBgYHtyfQ0KIyNDaGVjayBub3JtYWxpdHkNCmhpc3QoVG9sRGF0YV9NNCRDaGwucHJvcCkNCnNoYXBpcm8udGVzdChUb2xEYXRhX000JENobC5wcm9wKQ0KI05vdCBOb3JtYWwNCg0KIyNUcnkgbG9nKzEgdHJhbnNmb3JtYXRpb24NCmhpc3QobG9nKFRvbERhdGFfTTQkQ2hsLnByb3ArMSkpDQpzaGFwaXJvLnRlc3QobG9nKFRvbERhdGFfTTQkQ2hsLnByb3ArMSkpDQojTm9ybWFsDQoNCiMjTW9kZWwgYXMgYSBmdW5jdGlvbiBvZiBTaXRlIGFuZCBHZW5vdHlwZQ0KIyNNb2RlbCB3aXRoIGxvZyB0cmFuc2Zvcm1hdGlvbg0KVG9sX0NobF9NNF9sbTwtbG0obG9nKENobC5wcm9wKzEpflNpdGUrR2Vub3R5cGUrU2l0ZTpHZW5vdHlwZSwgZGF0YT1Ub2xEYXRhX000KQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX0NobF9NNF9sbSkpKQ0KDQojUS1RIHBsb3QNCnFxbm9ybShyZXNpZChUb2xfQ2hsX000X2xtKSk7IHFxbGluZShyZXNpZChUb2xfQ2hsX000X2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9DaGxfTTRfbG0pLCByZXNpZChUb2xfQ2hsX000X2xtKSkNCg0KYGBgDQoNCg0KIyMjIE1vZGVsIFJlc3VsdHMNCg0KIyMjIyBPdmVyYWxsDQpgYGB7cn0NCiNNb2RlbCBSZXN1bHRzDQpzdW1tYXJ5KFRvbF9DaGxfTTRfbG0pDQphbm92YShUb2xfQ2hsX000X2xtKQ0KDQojRWZmZWN0IFNpemUgb2YgUHJlZGljdG9ycw0KZXRhX3NxdWFyZWQoVG9sX0NobF9NNF9sbSwgcGFydGlhbD1GQUxTRSkNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9DaGxfTTRfbG0ucmVzPC1kYXRhLmZyYW1lKGFub3ZhKFRvbF9DaGxfTTRfbG0pKQ0KVG9sX0NobF9NNF9sbS5yZXMkUHJlZGljdG9yPC1yb3duYW1lcyhUb2xfQ2hsX000X2xtLnJlcykNClRvbF9DaGxfTTRfbG0ucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9DaGxfTTRfbG0sIHBhcnRpYWw9RkFMU0UpJEV0YTIsIE5BKQ0KVG9sX0NobF9NNF9sbS5yZXMkUmVzcG9uc2U8LXJlcCgiQ2hsb3JvcGh5bGwiLCBucm93KFRvbF9DaGxfTTRfbG0ucmVzKSkNClRvbF9DaGxfTTRfbG0ucmVzJFRpbWVQPC1yZXAoIk00IiwgbnJvdyhUb2xfQ2hsX000X2xtLnJlcykpDQpUb2xfQ2hsX000X2xtLnJlczwtVG9sX0NobF9NNF9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KDQpTaWduaWZpY2FudCBlZmZlY3Qgb2YgU2l0ZSBhbmQgR2Vub3R5cGUgYW5kIFNpdGUqR2Vub3R5cGUuDQoNCg0KIyMjIyBQYWlyd2lzZQ0KYGBge3J9DQojUGFpcndpc2UgY29tcGFyaXNvbnMgYWNyb3NzOg0KDQojR2Vub3R5cGVzIHdpdGhpbiBTaXRlcw0KZW1tZWFucyhUb2xfQ2hsX000X2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQplbW1lYW5zKFRvbF9DaGxfTTRfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkNCg0KIyNTYXZlIHAtdmFsdWVzDQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQpUb2xfQ2hsX000X2xtLmdlbm88LWRhdGEuZnJhbWUoZW1tZWFucyhUb2xfQ2hsX000X2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpJGNvbnRyYXN0cykNClRvbF9DaGxfTTRfbG0uZ2VubzwtVG9sX0NobF9NNF9sbS5nZW5vICU+JSBzZXBhcmF0ZShjb2w9Y29udHJhc3QsIGludG89YygiZ3JvdXAxIiwgImdyb3VwMiIpLCBzZXA9IiAtICIsIHJlbW92ZT1UUlVFKQ0KVG9sX0NobF9NNF9sbS5nZW5vJGdyb3VwMTwtcGFzdGUoVG9sX0NobF9NNF9sbS5nZW5vJFNpdGUsIFRvbF9DaGxfTTRfbG0uZ2VubyRncm91cDEsIHNlcD0iXyIpDQpUb2xfQ2hsX000X2xtLmdlbm8kZ3JvdXAyPC1wYXN0ZShUb2xfQ2hsX000X2xtLmdlbm8kU2l0ZSwgVG9sX0NobF9NNF9sbS5nZW5vJGdyb3VwMiwgc2VwPSJfIikNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNClRvbF9DaGxfTTRfbG0uc2l0ZTwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9DaGxfTTRfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkkY29udHJhc3RzKQ0KVG9sX0NobF9NNF9sbS5zaXRlPC1Ub2xfQ2hsX000X2xtLnNpdGUgJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfQ2hsX000X2xtLnNpdGUkZ3JvdXAxPC1wYXN0ZShUb2xfQ2hsX000X2xtLnNpdGUkZ3JvdXAxLCBUb2xfQ2hsX000X2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQpUb2xfQ2hsX000X2xtLnNpdGUkZ3JvdXAyPC1wYXN0ZShUb2xfQ2hsX000X2xtLnNpdGUkZ3JvdXAyLCBUb2xfQ2hsX000X2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQoNCiNGdWxsIGxpc3Qgb2YgcC12YWx1ZXMNClRvbF9DaGxfTTRfbG0ucDwtcmJpbmQoVG9sX0NobF9NNF9sbS5nZW5vWyxjKDE6Miw0OjgpXSwgVG9sX0NobF9NNF9sbS5zaXRlWyxjKDE6Miw0OjgpXSkNClRvbF9DaGxfTTRfbG0ucDwtVG9sX0NobF9NNF9sbS5wICU+JSBkcGx5cjo6cmVuYW1lKCBwID0gcC52YWx1ZSkNCg0KI0FkZCBTaWduaWZpY2FuY2UgTGV2ZWxzDQpUb2xfQ2hsX000X2xtLnAkU2lnPC1pZmVsc2UoVG9sX0NobF9NNF9sbS5wJHA8MC4wMDEsICIqKioiLCBpZmVsc2UoVG9sX0NobF9NNF9sbS5wJHA8MC4wMSwgIioqIiwgaWZlbHNlKFRvbF9DaGxfTTRfbG0ucCRwPDAuMDUsICIqIiwgTkEpKSkNCg0KI1NwZWNpZnkgUmVzcG9uc2UgYW5kIFRpbWVwb2ludA0KVG9sX0NobF9NNF9sbS5wJFJlc3BvbnNlPC1yZXAoIkNobG9yb3BoeWxsIiwgbnJvdyhUb2xfQ2hsX000X2xtLnApKQ0KVG9sX0NobF9NNF9sbS5wJFRpbWVQPC1yZXAoIk00IiwgbnJvdyhUb2xfQ2hsX000X2xtLnApKQ0KDQpgYGANCg0KDQojIyMgUGxvdCBSZXRlbnRpb24gYnkgU2l0ZSBhbmQgR2Vub3R5cGUNCmBgYHtyfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgR2Vub3R5cGUNClRvbF9DaGxfTTRfU0c8LXN1bW1hcnlTRShUb2xEYXRhX000LCBtZWFzdXJldmFyPSJDaGwucHJvcCIsIGdyb3VwdmFycz1jKCJTaXRlLkdlbm8iLCAiU2l0ZSIsICJHZW5vdHlwZSIpLCBuYS5ybT1UUlVFKQ0KDQojI1Bsb3QgQXZlcmFnZSBSZXRlbnRpb24gYWNyb3NzIFRyZWF0bWVudHMNClRvbF9DaGxfTTRfU0cucGxvdDwtZ2dwbG90KFRvbF9DaGxfTTRfU0csIGFlcyh4PVNpdGUuR2VubywgeT1DaGwucHJvcCwgY29sb3VyPUdlbm90eXBlKSkgKyANCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1DaGwucHJvcC1zZSwgeW1heD1DaGwucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeikrDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeikrIA0KICAgZ2d0aXRsZSgiQ2hsb3JvcGh5bGwgUmV0ZW50aW9uIikrDQogIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCANCiAgICAgICAgbGVnZW5kLmRpcmVjdGlvbj0iaG9yaXpvbnRhbCIsDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IlByb3BvcnRpb24gUmV0YWluZWQiKSsNCiAgeWxpbSgwLCAxKSsgDQogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIiIsIktsZWluIiwiIiwiIiwiU29tZXRoaW5nIFNwZWNpYWwiLCIiKSkrDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBHZW5vLmNvbG9ycy5vKSsgDQogIHN0YXRfcHZhbHVlX21hbnVhbChkYXRhPVRvbF9DaGxfTTRfbG0ucCwgIHkucG9zaXRpb249MC41NSwgc3RlcC5pbmNyZWFzZT0wLjIwLCBsYWJlbD0iU2lnIiwgaGlkZS5ucz1UUlVFKTsgVG9sX0NobF9NNF9TRy5wbG90DQoNCmBgYA0KDQoNCiMgVGhlcm1hbCBUb2xlcmFuY2UgU3ltYmlvbnRzDQoNCiMjIEZ1bGwgU2V0DQoNCiMjIyBSdW4gTW9kZWwNCmBgYHtyfQ0KIyNDaGVjayBub3JtYWxpdHkNCmhpc3QoVG9sRGF0YSRTeW0ucHJvcCkNCnNoYXBpcm8udGVzdChUb2xEYXRhJFN5bS5wcm9wKQ0KI05vdCBOb3JtYWwNCg0KIyNUcnkgbG9nKzEgdHJhbnNmb3JtYXRpb24NCmhpc3QobG9nKFRvbERhdGEkU3ltLnByb3ArMSkpDQpzaGFwaXJvLnRlc3QobG9nKFRvbERhdGEkU3ltLnByb3ArMSkpDQojTm90IG5vcm1hbCANCg0KIyNUcnkgc3F1YXJlIHRyYW5zZm9ybWF0aW9uDQpoaXN0KChUb2xEYXRhJFN5bS5wcm9wKV4yKQ0Kc2hhcGlyby50ZXN0KChUb2xEYXRhJFN5bS5wcm9wKV4yKQ0KI05vdCBub3JtYWwgDQoNCiMjVHJ5IGN1YmVkIHRyYW5zZm9ybWF0aW9uDQpoaXN0KChUb2xEYXRhJFN5bS5wcm9wKV4zKQ0Kc2hhcGlyby50ZXN0KChUb2xEYXRhJFN5bS5wcm9wKV4zKQ0KI05vdCBub3JtYWwgDQoNCg0KIyNNb2RlbCBhcyBhIGZ1bmN0aW9uIG9mIFNpdGUgYW5kIEdlbm90eXBlIGFuZCBUaW1lcG9pbnQNCiMjTW9kZWwgd2l0aCBubyB0cmFuc2Zvcm1hdGlvbiBhbmQgY2hlY2sgcmVzaWR1YWxzDQpUb2xfU3ltX2xtPC1sbShTeW0ucHJvcH5TaXRlK0dlbm90eXBlK1RpbWVQKyBTaXRlOkdlbm90eXBlICsgU2l0ZTpUaW1lUCArIEdlbm90eXBlOlRpbWVQLCBkYXRhPVRvbERhdGEpDQoNCmBgYA0KDQoNCiMjIyMgQ2hlY2sgUmVzaWR1YWxzDQpgYGB7cn0NCiMjQ2hlY2sgTm9ybWFsaXR5IG9mIFJlc2lkdWFscw0KI0Rpc3RyaWJ1dGlvbiANCnBsb3QoZGVuc2l0eShyZXNpZChUb2xfU3ltX2xtKSkpDQoNCiNRLVEgcGxvdA0KcXFub3JtKHJlc2lkKFRvbF9TeW1fbG0pKTsgcXFsaW5lKHJlc2lkKFRvbF9TeW1fbG0pKQ0KDQojI0NoZWNrIFZhcmlhbmNlIG9mIFJlc2lkdWFscyBhY3Jvc3MgRml0dGVkIFZhbHVlcw0KcGxvdChmaXR0ZWQoVG9sX1N5bV9sbSksIHJlc2lkKFRvbF9TeW1fbG0pKQ0KDQpgYGANCg0KDQojIyMgTW9kZWwgUmVzdWx0cw0KDQpgYGB7cn0NCiNNb2RlbCBSZXN1bHRzDQpzdW1tYXJ5KFRvbF9TeW1fbG0pDQphbm92YShUb2xfU3ltX2xtKQ0KDQojRWZmZWN0IFNpemUgb2YgUHJlZGljdG9ycw0KZXRhX3NxdWFyZWQoVG9sX1N5bV9sbSwgcGFydGlhbD1GQUxTRSkNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9TeW1fbG0ucmVzPC1kYXRhLmZyYW1lKGFub3ZhKFRvbF9TeW1fbG0pKQ0KVG9sX1N5bV9sbS5yZXMkUHJlZGljdG9yPC1yb3duYW1lcyhUb2xfU3ltX2xtLnJlcykNClRvbF9TeW1fbG0ucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9TeW1fbG0sIHBhcnRpYWw9RkFMU0UpJEV0YTIsIE5BKQ0KVG9sX1N5bV9sbS5yZXMkUmVzcG9uc2U8LXJlcCgiU3ltYmlvbnRzIiwgbnJvdyhUb2xfU3ltX2xtLnJlcykpDQpUb2xfU3ltX2xtLnJlczwtVG9sX1N5bV9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KU3Ryb25nIGluZmx1ZW5jZSBvZiBUaW1lcG9pbnQsIGluY2x1ZGluZyBpbnRlcmFjdGlvbnMgd2l0aCBtYWluIHZhcmlhYmxlcyBvZiBpbnRlcmVzdCwgU2l0ZSBhbmQgR2Vub3R5cGUuIFdpbGwgYW5hbHl6ZSBlYWNoIFRpbWVwb2ludCBpbmRpdmlkdWFsbHkuIA0KDQoNCiMjIFN5bSBTdW1tZXIgMSBUaW1lcG9pbnQgVzINCg0KIyMjIFJ1biBNb2RlbA0KYGBge3J9DQojI0NoZWNrIG5vcm1hbGl0eQ0KaGlzdChUb2xEYXRhX1cyJFN5bS5wcm9wKQ0Kc2hhcGlyby50ZXN0KFRvbERhdGFfVzIkU3ltLnByb3ApDQojTm9ybWFsDQoNCiMjTW9kZWwgYXMgYSBmdW5jdGlvbiBvZiBTaXRlIGFuZCBHZW5vdHlwZQ0KVG9sX1N5bV9XMl9sbTwtbG0oU3ltLnByb3B+U2l0ZStHZW5vdHlwZStTaXRlOkdlbm90eXBlLCBkYXRhPVRvbERhdGFfVzIpDQoNCmBgYA0KDQoNCiMjIyMgQ2hlY2sgUmVzaWR1YWxzDQpgYGB7cn0NCiMjQ2hlY2sgTm9ybWFsaXR5IG9mIFJlc2lkdWFscw0KI0Rpc3RyaWJ1dGlvbiANCnBsb3QoZGVuc2l0eShyZXNpZChUb2xfU3ltX1cyX2xtKSkpDQoNCiNRLVEgcGxvdA0KcXFub3JtKHJlc2lkKFRvbF9TeW1fVzJfbG0pKTsgcXFsaW5lKHJlc2lkKFRvbF9TeW1fVzJfbG0pKQ0KDQojI0NoZWNrIFZhcmlhbmNlIG9mIFJlc2lkdWFscyBhY3Jvc3MgRml0dGVkIFZhbHVlcw0KcGxvdChmaXR0ZWQoVG9sX1N5bV9XMl9sbSksIHJlc2lkKFRvbF9TeW1fVzJfbG0pKQ0KDQpgYGANCg0KDQojIyMgTW9kZWwgUmVzdWx0cw0KDQojIyMjIE92ZXJhbGwNCmBgYHtyfQ0KI01vZGVsIFJlc3VsdHMNCnN1bW1hcnkoVG9sX1N5bV9XMl9sbSkNCmFub3ZhKFRvbF9TeW1fVzJfbG0pDQoNCiNFZmZlY3QgU2l6ZSBvZiBQcmVkaWN0b3JzDQpldGFfc3F1YXJlZChUb2xfU3ltX1cyX2xtLCBwYXJ0aWFsPUZBTFNFKQ0KDQojI1NhdmUgbW9kZWwgcmVzdWx0cw0KVG9sX1N5bV9XMl9sbS5yZXM8LWRhdGEuZnJhbWUoYW5vdmEoVG9sX1N5bV9XMl9sbSkpDQpUb2xfU3ltX1cyX2xtLnJlcyRQcmVkaWN0b3I8LXJvd25hbWVzKFRvbF9TeW1fVzJfbG0ucmVzKQ0KVG9sX1N5bV9XMl9sbS5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoVG9sX1N5bV9XMl9sbSwgcGFydGlhbD1GQUxTRSkkRXRhMiwgTkEpDQpUb2xfU3ltX1cyX2xtLnJlcyRSZXNwb25zZTwtcmVwKCJTeW1iaW9udHMiLCBucm93KFRvbF9TeW1fVzJfbG0ucmVzKSkNClRvbF9TeW1fVzJfbG0ucmVzJFRpbWVQPC1yZXAoIlcyIiwgbnJvdyhUb2xfU3ltX1cyX2xtLnJlcykpDQpUb2xfU3ltX1cyX2xtLnJlczwtVG9sX1N5bV9XMl9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KDQpTaWduaWZpY2FudCBlZmZlY3Qgb2YgU2l0ZSBhbmQgR2Vub3R5cGUuIE1hcmdpbmFsIGVmZmVjdCAocDwwLjEpIG9mIFNpdGUgKiBHZW5vdHlwZS4gU3RpbGwgY2hlY2tpbmcgU2l0ZSpHZW5vdHlwZSBmb3IgY29tcGFyYWJpbGl0eSBhY3Jvc3MgVGltZXBvaW50cy4NCg0KDQoNCiMjIyMgUGFpcndpc2UNCmBgYHtyfQ0KI1BhaXJ3aXNlIGNvbXBhcmlzb25zIGFjcm9zczoNCg0KI0dlbm90eXBlcyB3aXRoaW4gU2l0ZXMNCmVtbWVhbnMoVG9sX1N5bV9XMl9sbSwgcGFpcndpc2V+R2Vub3R5cGUgfCBTaXRlKQ0KDQojU2l0ZXMgd2l0aGluIEdlbm90eXBlcw0KZW1tZWFucyhUb2xfU3ltX1cyX2xtLCBwYWlyd2lzZX5TaXRlIHwgR2Vub3R5cGUpDQoNCiMjU2F2ZSBwLXZhbHVlcw0KDQojR2Vub3R5cGVzIHdpdGhpbiBTaXRlcw0KVG9sX1N5bV9XMl9sbS5nZW5vPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1N5bV9XMl9sbSwgcGFpcndpc2V+R2Vub3R5cGUgfCBTaXRlKSRjb250cmFzdHMpDQpUb2xfU3ltX1cyX2xtLmdlbm88LVRvbF9TeW1fVzJfbG0uZ2VubyAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TeW1fVzJfbG0uZ2VubyRncm91cDE8LXBhc3RlKFRvbF9TeW1fVzJfbG0uZ2VubyRTaXRlLCBUb2xfU3ltX1cyX2xtLmdlbm8kZ3JvdXAxLCBzZXA9Il8iKQ0KVG9sX1N5bV9XMl9sbS5nZW5vJGdyb3VwMjwtcGFzdGUoVG9sX1N5bV9XMl9sbS5nZW5vJFNpdGUsIFRvbF9TeW1fVzJfbG0uZ2VubyRncm91cDIsIHNlcD0iXyIpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQpUb2xfU3ltX1cyX2xtLnNpdGU8LWRhdGEuZnJhbWUoZW1tZWFucyhUb2xfU3ltX1cyX2xtLCBwYWlyd2lzZX5TaXRlIHwgR2Vub3R5cGUpJGNvbnRyYXN0cykNClRvbF9TeW1fVzJfbG0uc2l0ZTwtVG9sX1N5bV9XMl9sbS5zaXRlICU+JSBzZXBhcmF0ZShjb2w9Y29udHJhc3QsIGludG89YygiZ3JvdXAxIiwgImdyb3VwMiIpLCBzZXA9IiAtICIsIHJlbW92ZT1UUlVFKQ0KVG9sX1N5bV9XMl9sbS5zaXRlJGdyb3VwMTwtcGFzdGUoVG9sX1N5bV9XMl9sbS5zaXRlJGdyb3VwMSwgVG9sX1N5bV9XMl9sbS5zaXRlJEdlbm90eXBlLCBzZXA9Il8iKQ0KVG9sX1N5bV9XMl9sbS5zaXRlJGdyb3VwMjwtcGFzdGUoVG9sX1N5bV9XMl9sbS5zaXRlJGdyb3VwMiwgVG9sX1N5bV9XMl9sbS5zaXRlJEdlbm90eXBlLCBzZXA9Il8iKQ0KDQojRnVsbCBsaXN0IG9mIHAtdmFsdWVzDQpUb2xfU3ltX1cyX2xtLnA8LXJiaW5kKFRvbF9TeW1fVzJfbG0uZ2Vub1ssYygxOjIsNDo4KV0sIFRvbF9TeW1fVzJfbG0uc2l0ZVssYygxOjIsNDo4KV0pDQpUb2xfU3ltX1cyX2xtLnA8LVRvbF9TeW1fVzJfbG0ucCAlPiUgZHBseXI6OnJlbmFtZSggcCA9IHAudmFsdWUpDQoNCiNBZGQgU2lnbmlmaWNhbmNlIExldmVscw0KVG9sX1N5bV9XMl9sbS5wJFNpZzwtaWZlbHNlKFRvbF9TeW1fVzJfbG0ucCRwPDAuMDAxLCAiKioqIiwgaWZlbHNlKFRvbF9TeW1fVzJfbG0ucCRwPDAuMDEsICIqKiIsIGlmZWxzZShUb2xfU3ltX1cyX2xtLnAkcDwwLjA1LCAiKiIsIE5BKSkpDQoNCiNTcGVjaWZ5IFJlc3BvbnNlIGFuZCBUaW1lcG9pbnQNClRvbF9TeW1fVzJfbG0ucCRSZXNwb25zZTwtcmVwKCJTeW1iaW9udHMiLCBucm93KFRvbF9TeW1fVzJfbG0ucCkpDQpUb2xfU3ltX1cyX2xtLnAkVGltZVA8LXJlcCgiVzIiLCBucm93KFRvbF9TeW1fVzJfbG0ucCkpDQoNCmBgYA0KDQoNCiMjIyBQbG90IFJldGVudGlvbiBieSBTaXRlIGFuZCBHZW5vdHlwZQ0KYGBge3J9DQojI1N1bW1hcnkgc3RhdGlzdGljcyBieSBTaXRlIGFuZCBHZW5vdHlwZQ0KVG9sX1N5bV9XMl9TRzwtc3VtbWFyeVNFKFRvbERhdGFfVzIsIG1lYXN1cmV2YXI9IlN5bS5wcm9wIiwgZ3JvdXB2YXJzPWMoIlNpdGUuR2VubyIsICJTaXRlIiwgIkdlbm90eXBlIiksIG5hLnJtPVRSVUUpDQoNCiMjUGxvdCBBdmVyYWdlIFJldGVudGlvbiBhY3Jvc3MgVHJlYXRtZW50cw0KVG9sX1N5bV9XMl9TRy5wbG90PC1nZ3Bsb3QoVG9sX1N5bV9XMl9TRywgYWVzKHg9U2l0ZS5HZW5vLCB5PVN5bS5wcm9wLCBjb2xvdXI9R2Vub3R5cGUpKSArIA0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPVN5bS5wcm9wLXNlLCB5bWF4PVN5bS5wcm9wK3NlKSwgd2lkdGg9Y2FwLnN6LCBsaW5ld2lkdGg9YmFyLnN6KSsNCiAgZ2VvbV9wb2ludChzaXplPXBvaW50LnN6KSsgDQogICBnZ3RpdGxlKCJTeW1iaW9udCBSZXRlbnRpb24iKSsNCiAgdGhlbWVfY2xhc3NpYygpKw0KICB0aGVtZSggYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLA0KICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsIA0KICAgICAgICBsZWdlbmQuZGlyZWN0aW9uPSJob3Jpem9udGFsIiwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gcGxvdC50aXRsZS5zeiwgY29sb3VyPSJibGFjayIsIGhqdXN0ID0gMC41KSkrDQogIGxhYnMoeD0iIiwgeT0iUHJvcG9ydGlvbiBSZXRhaW5lZCIpKw0KICB5bGltKDAsIDEuNSkrIA0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIiLCJLbGVpbiIsIiIsIiIsIlNvbWV0aGluZyBTcGVjaWFsIiwiIikpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gR2Vuby5jb2xvcnMubykrIA0KICBzdGF0X3B2YWx1ZV9tYW51YWwoZGF0YT1Ub2xfU3ltX1cyX2xtLnAsICB5LnBvc2l0aW9uPTAuOTUsIHN0ZXAuaW5jcmVhc2U9MC4xNSwgbGFiZWw9IlNpZyIsIGhpZGUubnM9VFJVRSk7IFRvbF9TeW1fVzJfU0cucGxvdA0KDQpgYGANCg0KDQojIyBTeW0gU3VtbWVyIDIgVGltZXBvaW50IE0xDQoNCiMjIyBSdW4gTW9kZWwNCmBgYHtyfQ0KIyNDaGVjayBub3JtYWxpdHkNCmhpc3QoVG9sRGF0YV9NMSRTeW0ucHJvcCkNCnNoYXBpcm8udGVzdChUb2xEYXRhX00xJFN5bS5wcm9wKQ0KI05vdCBub3JtYWwNCg0KIyNUcnkgbG9nKzEgdHJhbnNmb3JtYXRpb24NCmhpc3QobG9nKFRvbERhdGFfTTEkU3ltLnByb3ArMSkpDQpzaGFwaXJvLnRlc3QobG9nKFRvbERhdGFfTTEkU3ltLnByb3ArMSkpDQojTm90IG5vcm1hbCBidXQgaW1wcm92ZWQNCg0KIyNNb2RlbCBhcyBhIGZ1bmN0aW9uIG9mIFNpdGUgYW5kIEdlbm90eXBlDQojI01vZGVsIHdpdGggbG9nIHRyYW5zZm9ybWF0aW9uDQpUb2xfU3ltX00xX2xtPC1sbShsb2coU3ltLnByb3ArMSl+U2l0ZStHZW5vdHlwZStTaXRlOkdlbm90eXBlLCBkYXRhPVRvbERhdGFfTTEpDQoNCmBgYA0KDQoNCiMjIyMgQ2hlY2sgUmVzaWR1YWxzDQpgYGB7cn0NCiMjQ2hlY2sgTm9ybWFsaXR5IG9mIFJlc2lkdWFscw0KI0Rpc3RyaWJ1dGlvbiANCnBsb3QoZGVuc2l0eShyZXNpZChUb2xfU3ltX00xX2xtKSkpDQoNCiNRLVEgcGxvdA0KcXFub3JtKHJlc2lkKFRvbF9TeW1fTTFfbG0pKTsgcXFsaW5lKHJlc2lkKFRvbF9TeW1fTTFfbG0pKQ0KDQojI0NoZWNrIFZhcmlhbmNlIG9mIFJlc2lkdWFscyBhY3Jvc3MgRml0dGVkIFZhbHVlcw0KcGxvdChmaXR0ZWQoVG9sX1N5bV9NMV9sbSksIHJlc2lkKFRvbF9TeW1fTTFfbG0pKQ0KDQpgYGANCg0KDQojIyMgTW9kZWwgUmVzdWx0cw0KDQojIyMjIE92ZXJhbGwNCmBgYHtyfQ0KI01vZGVsIFJlc3VsdHMNCnN1bW1hcnkoVG9sX1N5bV9NMV9sbSkNCmFub3ZhKFRvbF9TeW1fTTFfbG0pDQoNCiNFZmZlY3QgU2l6ZSBvZiBQcmVkaWN0b3JzDQpldGFfc3F1YXJlZChUb2xfU3ltX00xX2xtLCBwYXJ0aWFsPUZBTFNFKQ0KDQojI1NhdmUgbW9kZWwgcmVzdWx0cw0KVG9sX1N5bV9NMV9sbS5yZXM8LWRhdGEuZnJhbWUoYW5vdmEoVG9sX1N5bV9NMV9sbSkpDQpUb2xfU3ltX00xX2xtLnJlcyRQcmVkaWN0b3I8LXJvd25hbWVzKFRvbF9TeW1fTTFfbG0ucmVzKQ0KVG9sX1N5bV9NMV9sbS5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoVG9sX1N5bV9NMV9sbSwgcGFydGlhbD1GQUxTRSkkRXRhMiwgTkEpDQpUb2xfU3ltX00xX2xtLnJlcyRSZXNwb25zZTwtcmVwKCJTeW1iaW9udHMiLCBucm93KFRvbF9TeW1fTTFfbG0ucmVzKSkNClRvbF9TeW1fTTFfbG0ucmVzJFRpbWVQPC1yZXAoIk0xIiwgbnJvdyhUb2xfU3ltX00xX2xtLnJlcykpDQpUb2xfU3ltX00xX2xtLnJlczwtVG9sX1N5bV9NMV9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KDQpTaWduaWZpY2FudCBlZmZlY3Qgb2YgR2Vub3R5cGUuIFN0aWxsIGNoZWNraW5nIFNpdGUqR2Vub3R5cGUgZm9yIGNvbXBhcmFiaWxpdHkgYWNyb3NzIFRpbWVwb2ludHMuDQoNCg0KIyMjIyBQYWlyd2lzZQ0KYGBge3J9DQojUGFpcndpc2UgY29tcGFyaXNvbnMgYWNyb3NzOg0KDQojR2Vub3R5cGVzIHdpdGhpbiBTaXRlcw0KZW1tZWFucyhUb2xfU3ltX00xX2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQplbW1lYW5zKFRvbF9TeW1fTTFfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkNCg0KIyNTYXZlIHAtdmFsdWVzDQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQpUb2xfU3ltX00xX2xtLmdlbm88LWRhdGEuZnJhbWUoZW1tZWFucyhUb2xfU3ltX00xX2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpJGNvbnRyYXN0cykNClRvbF9TeW1fTTFfbG0uZ2VubzwtVG9sX1N5bV9NMV9sbS5nZW5vICU+JSBzZXBhcmF0ZShjb2w9Y29udHJhc3QsIGludG89YygiZ3JvdXAxIiwgImdyb3VwMiIpLCBzZXA9IiAtICIsIHJlbW92ZT1UUlVFKQ0KVG9sX1N5bV9NMV9sbS5nZW5vJGdyb3VwMTwtcGFzdGUoVG9sX1N5bV9NMV9sbS5nZW5vJFNpdGUsIFRvbF9TeW1fTTFfbG0uZ2VubyRncm91cDEsIHNlcD0iXyIpDQpUb2xfU3ltX00xX2xtLmdlbm8kZ3JvdXAyPC1wYXN0ZShUb2xfU3ltX00xX2xtLmdlbm8kU2l0ZSwgVG9sX1N5bV9NMV9sbS5nZW5vJGdyb3VwMiwgc2VwPSJfIikNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNClRvbF9TeW1fTTFfbG0uc2l0ZTwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9TeW1fTTFfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkkY29udHJhc3RzKQ0KVG9sX1N5bV9NMV9sbS5zaXRlPC1Ub2xfU3ltX00xX2xtLnNpdGUgJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfU3ltX00xX2xtLnNpdGUkZ3JvdXAxPC1wYXN0ZShUb2xfU3ltX00xX2xtLnNpdGUkZ3JvdXAxLCBUb2xfU3ltX00xX2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQpUb2xfU3ltX00xX2xtLnNpdGUkZ3JvdXAyPC1wYXN0ZShUb2xfU3ltX00xX2xtLnNpdGUkZ3JvdXAyLCBUb2xfU3ltX00xX2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQoNCiNGdWxsIGxpc3Qgb2YgcC12YWx1ZXMNClRvbF9TeW1fTTFfbG0ucDwtcmJpbmQoVG9sX1N5bV9NMV9sbS5nZW5vWyxjKDE6Miw0OjgpXSwgVG9sX1N5bV9NMV9sbS5zaXRlWyxjKDE6Miw0OjgpXSkNClRvbF9TeW1fTTFfbG0ucDwtVG9sX1N5bV9NMV9sbS5wICU+JSBkcGx5cjo6cmVuYW1lKCBwID0gcC52YWx1ZSkNCg0KI0FkZCBTaWduaWZpY2FuY2UgTGV2ZWxzDQpUb2xfU3ltX00xX2xtLnAkU2lnPC1pZmVsc2UoVG9sX1N5bV9NMV9sbS5wJHA8MC4wMDEsICIqKioiLCBpZmVsc2UoVG9sX1N5bV9NMV9sbS5wJHA8MC4wMSwgIioqIiwgaWZlbHNlKFRvbF9TeW1fTTFfbG0ucCRwPDAuMDUsICIqIiwgTkEpKSkNCg0KI1NwZWNpZnkgUmVzcG9uc2UgYW5kIFRpbWVwb2ludA0KVG9sX1N5bV9NMV9sbS5wJFJlc3BvbnNlPC1yZXAoIlN5bWJpb250cyIsIG5yb3coVG9sX1N5bV9NMV9sbS5wKSkNClRvbF9TeW1fTTFfbG0ucCRUaW1lUDwtcmVwKCJNMSIsIG5yb3coVG9sX1N5bV9NMV9sbS5wKSkNCg0KYGBgDQoNCg0KIyMjIFBsb3QgUmV0ZW50aW9uIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpgYGB7cn0NCiMjU3VtbWFyeSBzdGF0aXN0aWNzIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpUb2xfU3ltX00xX1NHPC1zdW1tYXJ5U0UoVG9sRGF0YV9NMSwgbWVhc3VyZXZhcj0iU3ltLnByb3AiLCBncm91cHZhcnM9YygiU2l0ZS5HZW5vIiwgIlNpdGUiLCAiR2Vub3R5cGUiKSwgbmEucm09VFJVRSkNCg0KIyNQbG90IEF2ZXJhZ2UgUmV0ZW50aW9uIGFjcm9zcyBUcmVhdG1lbnRzDQpUb2xfU3ltX00xX1NHLnBsb3Q8LWdncGxvdChUb2xfU3ltX00xX1NHLCBhZXMoeD1TaXRlLkdlbm8sIHk9U3ltLnByb3AsIGNvbG91cj1HZW5vdHlwZSkpICsgDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49U3ltLnByb3Atc2UsIHltYXg9U3ltLnByb3Arc2UpLCB3aWR0aD1jYXAuc3osIGxpbmV3aWR0aD1iYXIuc3opKw0KICBnZW9tX3BvaW50KHNpemU9cG9pbnQuc3opKyANCiAgIGdndGl0bGUoIlN5bWJpb250IFJldGVudGlvbiIpKw0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKCBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksDQogICAgICAgIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIiksDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwgDQogICAgICAgIGxlZ2VuZC5kaXJlY3Rpb249Imhvcml6b250YWwiLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBwbG90LnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgaGp1c3QgPSAwLjUpKSsNCiAgbGFicyh4PSIiLCB5PSJQcm9wb3J0aW9uIFJldGFpbmVkIikrDQogeWxpbSgwLCAxLjUpKyANCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiIiwiS2xlaW4iLCIiLCIiLCJTb21ldGhpbmcgU3BlY2lhbCIsIiIpKSsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IEdlbm8uY29sb3JzLm8pKyANCiAgc3RhdF9wdmFsdWVfbWFudWFsKGRhdGE9VG9sX1N5bV9NMV9sbS5wLCAgeS5wb3NpdGlvbj0wLjk1LCBzdGVwLmluY3JlYXNlPTAuMTUsIGxhYmVsPSJTaWciLCBoaWRlLm5zPVRSVUUpOyBUb2xfU3ltX00xX1NHLnBsb3QNCg0KYGBgDQoNCg0KIyMgU3ltIFdpbnRlciBUaW1lcG9pbnQgTTQNCg0KIyMjIFJ1biBNb2RlbA0KYGBge3J9DQojI0NoZWNrIG5vcm1hbGl0eQ0KaGlzdChUb2xEYXRhX000JFN5bS5wcm9wKQ0Kc2hhcGlyby50ZXN0KFRvbERhdGFfTTQkU3ltLnByb3ApDQojTm90IE5vcm1hbA0KDQojI1RyeSBzcXVhcmUgdHJhbnNmb3JtYXRpb24NCmhpc3QoKFRvbERhdGFfTTQkU3ltLnByb3ApXjIpDQpzaGFwaXJvLnRlc3QoKFRvbERhdGFfTTQkU3ltLnByb3ApXjIpDQojTm90IE5vcm1hbA0KDQojI1RyeSBjdWJlZCB0cmFuc2Zvcm1hdGlvbg0KaGlzdCgoVG9sRGF0YV9NNCRTeW0ucHJvcCleMykNCnNoYXBpcm8udGVzdCgoVG9sRGF0YV9NNCRTeW0ucHJvcCleMykNCiNOb3QgTm9ybWFsDQoNCiMjTW9kZWwgYXMgYSBmdW5jdGlvbiBvZiBTaXRlIGFuZCBHZW5vdHlwZQ0KIyNNb2RlbCB3aXRoIG5vIHRyYW5zZm9ybWF0aW9uIGFuZCBjaGVjayByZXNpZHVhbHMNClRvbF9TeW1fTTRfbG08LWxtKFN5bS5wcm9wflNpdGUrR2Vub3R5cGUrU2l0ZTpHZW5vdHlwZSwgZGF0YT1Ub2xEYXRhX000KQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX1N5bV9NNF9sbSkpKQ0KDQojUS1RIHBsb3QNCnFxbm9ybShyZXNpZChUb2xfU3ltX000X2xtKSk7IHFxbGluZShyZXNpZChUb2xfU3ltX000X2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9TeW1fTTRfbG0pLCByZXNpZChUb2xfU3ltX000X2xtKSkNCg0KYGBgDQoNCg0KIyMjIE1vZGVsIFJlc3VsdHMNCg0KIyMjIyBPdmVyYWxsDQpgYGB7cn0NCiNNb2RlbCBSZXN1bHRzDQpzdW1tYXJ5KFRvbF9TeW1fTTRfbG0pDQphbm92YShUb2xfU3ltX000X2xtKQ0KDQojRWZmZWN0IFNpemUgb2YgUHJlZGljdG9ycw0KZXRhX3NxdWFyZWQoVG9sX1N5bV9NNF9sbSwgcGFydGlhbD1GQUxTRSkNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9TeW1fTTRfbG0ucmVzPC1kYXRhLmZyYW1lKGFub3ZhKFRvbF9TeW1fTTRfbG0pKQ0KVG9sX1N5bV9NNF9sbS5yZXMkUHJlZGljdG9yPC1yb3duYW1lcyhUb2xfU3ltX000X2xtLnJlcykNClRvbF9TeW1fTTRfbG0ucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9TeW1fTTRfbG0sIHBhcnRpYWw9RkFMU0UpJEV0YTIsIE5BKQ0KVG9sX1N5bV9NNF9sbS5yZXMkUmVzcG9uc2U8LXJlcCgiU3ltYmlvbnRzIiwgbnJvdyhUb2xfU3ltX000X2xtLnJlcykpDQpUb2xfU3ltX000X2xtLnJlcyRUaW1lUDwtcmVwKCJNNCIsIG5yb3coVG9sX1N5bV9NNF9sbS5yZXMpKQ0KVG9sX1N5bV9NNF9sbS5yZXM8LVRvbF9TeW1fTTRfbG0ucmVzICU+JSBkcGx5cjo6cmVuYW1lKCBwLnZhbHVlID0gIlByLi5GLiIsIERGPSAiRGYiKQ0KDQpgYGANCg0KU2lnbmlmaWNhbnQgZWZmZWN0IG9mIFNpdGUgYW5kIEdlbm90eXBlLiBNYXJnaW5hbCBlZmZlY3QgKHA8MC4xKSBvZiBTaXRlICogR2Vub3R5cGUuIFN0aWxsIGNoZWNraW5nIFNpdGUqR2Vub3R5cGUgZm9yIGNvbXBhcmFiaWxpdHkgYWNyb3NzIFRpbWVwb2ludHMuDQoNCg0KDQojIyMjIFBhaXJ3aXNlDQpgYGB7cn0NCiNQYWlyd2lzZSBjb21wYXJpc29ucyBhY3Jvc3M6DQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQplbW1lYW5zKFRvbF9TeW1fTTRfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNCmVtbWVhbnMoVG9sX1N5bV9NNF9sbSwgcGFpcndpc2V+U2l0ZSB8IEdlbm90eXBlKQ0KDQojI1NhdmUgcC12YWx1ZXMNCg0KI0dlbm90eXBlcyB3aXRoaW4gU2l0ZXMNClRvbF9TeW1fTTRfbG0uZ2VubzwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9TeW1fTTRfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkkY29udHJhc3RzKQ0KVG9sX1N5bV9NNF9sbS5nZW5vPC1Ub2xfU3ltX000X2xtLmdlbm8gJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfU3ltX000X2xtLmdlbm8kZ3JvdXAxPC1wYXN0ZShUb2xfU3ltX000X2xtLmdlbm8kU2l0ZSwgVG9sX1N5bV9NNF9sbS5nZW5vJGdyb3VwMSwgc2VwPSJfIikNClRvbF9TeW1fTTRfbG0uZ2VubyRncm91cDI8LXBhc3RlKFRvbF9TeW1fTTRfbG0uZ2VubyRTaXRlLCBUb2xfU3ltX000X2xtLmdlbm8kZ3JvdXAyLCBzZXA9Il8iKQ0KDQojU2l0ZXMgd2l0aGluIEdlbm90eXBlcw0KVG9sX1N5bV9NNF9sbS5zaXRlPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1N5bV9NNF9sbSwgcGFpcndpc2V+U2l0ZSB8IEdlbm90eXBlKSRjb250cmFzdHMpDQpUb2xfU3ltX000X2xtLnNpdGU8LVRvbF9TeW1fTTRfbG0uc2l0ZSAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TeW1fTTRfbG0uc2l0ZSRncm91cDE8LXBhc3RlKFRvbF9TeW1fTTRfbG0uc2l0ZSRncm91cDEsIFRvbF9TeW1fTTRfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNClRvbF9TeW1fTTRfbG0uc2l0ZSRncm91cDI8LXBhc3RlKFRvbF9TeW1fTTRfbG0uc2l0ZSRncm91cDIsIFRvbF9TeW1fTTRfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNCg0KI0Z1bGwgbGlzdCBvZiBwLXZhbHVlcw0KVG9sX1N5bV9NNF9sbS5wPC1yYmluZChUb2xfU3ltX000X2xtLmdlbm9bLGMoMToyLDQ6OCldLCBUb2xfU3ltX000X2xtLnNpdGVbLGMoMToyLDQ6OCldKQ0KVG9sX1N5bV9NNF9sbS5wPC1Ub2xfU3ltX000X2xtLnAgJT4lIGRwbHlyOjpyZW5hbWUoIHAgPSBwLnZhbHVlKQ0KDQojQWRkIFNpZ25pZmljYW5jZSBMZXZlbHMNClRvbF9TeW1fTTRfbG0ucCRTaWc8LWlmZWxzZShUb2xfU3ltX000X2xtLnAkcDwwLjAwMSwgIioqKiIsIGlmZWxzZShUb2xfU3ltX000X2xtLnAkcDwwLjAxLCAiKioiLCBpZmVsc2UoVG9sX1N5bV9NNF9sbS5wJHA8MC4wNSwgIioiLCBOQSkpKQ0KDQojU3BlY2lmeSBSZXNwb25zZSBhbmQgVGltZXBvaW50DQpUb2xfU3ltX000X2xtLnAkUmVzcG9uc2U8LXJlcCgiU3ltYmlvbnRzIiwgbnJvdyhUb2xfU3ltX000X2xtLnApKQ0KVG9sX1N5bV9NNF9sbS5wJFRpbWVQPC1yZXAoIk00IiwgbnJvdyhUb2xfU3ltX000X2xtLnApKQ0KDQpgYGANCg0KDQojIyMgUGxvdCBSZXRlbnRpb24gYnkgU2l0ZSBhbmQgR2Vub3R5cGUNCmBgYHtyfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgR2Vub3R5cGUNClRvbF9TeW1fTTRfU0c8LXN1bW1hcnlTRShUb2xEYXRhX000LCBtZWFzdXJldmFyPSJTeW0ucHJvcCIsIGdyb3VwdmFycz1jKCJTaXRlLkdlbm8iLCAiU2l0ZSIsICJHZW5vdHlwZSIpLCBuYS5ybT1UUlVFKQ0KDQojI1Bsb3QgQXZlcmFnZSBSZXRlbnRpb24gYWNyb3NzIFRyZWF0bWVudHMNClRvbF9TeW1fTTRfU0cucGxvdDwtZ2dwbG90KFRvbF9TeW1fTTRfU0csIGFlcyh4PVNpdGUuR2VubywgeT1TeW0ucHJvcCwgY29sb3VyPUdlbm90eXBlKSkgKyANCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1TeW0ucHJvcC1zZSwgeW1heD1TeW0ucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeikrDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeikrIA0KICAgZ2d0aXRsZSgiU3ltYmlvbnQgUmV0ZW50aW9uIikrDQogIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCANCiAgICAgICAgbGVnZW5kLmRpcmVjdGlvbj0iaG9yaXpvbnRhbCIsDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IlByb3BvcnRpb24gUmV0YWluZWQiKSsNCiAgeWxpbSgwLCAxLjUpKyANCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiIiwiS2xlaW4iLCIiLCIiLCJTb21ldGhpbmcgU3BlY2lhbCIsIiIpKSsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IEdlbm8uY29sb3JzLm8pKyANCiAgc3RhdF9wdmFsdWVfbWFudWFsKGRhdGE9VG9sX1N5bV9NNF9sbS5wLCAgeS5wb3NpdGlvbj0xLjEsIHN0ZXAuaW5jcmVhc2U9MC4xNSwgbGFiZWw9IlNpZyIsIGhpZGUubnM9VFJVRSk7IFRvbF9TeW1fTTRfU0cucGxvdA0KDQpgYGANCg0KDQojIFRoZXJtYWwgVG9sZXJhbmNlIENvbG9yIEZ1bGwgU2V0DQoNCiMjIEZ1bGwgU2V0DQoNCiMjIyBSdW4gTW9kZWwNCmBgYHtyfQ0KIyNDaGVjayBub3JtYWxpdHkNCmhpc3QoVG9sRGF0YSRTY29yZV9GdWxsLnByb3ApDQpzaGFwaXJvLnRlc3QoVG9sRGF0YSRTY29yZV9GdWxsLnByb3ApDQojTm90IE5vcm1hbA0KDQojI1RyeSBzcXVhcmUgdHJhbnNmb3JtYXRpb24NCmhpc3QoKFRvbERhdGEkU2NvcmVfRnVsbC5wcm9wKV4yKQ0Kc2hhcGlyby50ZXN0KChUb2xEYXRhJFNjb3JlX0Z1bGwucHJvcCleMikNCiNOb3Qgbm9ybWFsIA0KDQojI1RyeSBjdWJlZCB0cmFuc2Zvcm1hdGlvbg0KaGlzdCgoVG9sRGF0YSRTY29yZV9GdWxsLnByb3ApXjMpDQpzaGFwaXJvLnRlc3QoKFRvbERhdGEkU2NvcmVfRnVsbC5wcm9wKV4zKQ0KI05vdCBub3JtYWwgDQoNCg0KIyNNb2RlbCBhcyBhIGZ1bmN0aW9uIG9mIFNpdGUgYW5kIEdlbm90eXBlIGFuZCBUaW1lcG9pbnQNCiMjTW9kZWwgd2l0aCBubyB0cmFuc2Zvcm1hdGlvbiBhbmQgY2hlY2sgcmVzaWR1YWxzDQpUb2xfU2NvcmVGX2xtPC1sbShTY29yZV9GdWxsLnByb3B+U2l0ZStHZW5vdHlwZStUaW1lUCsgU2l0ZTpHZW5vdHlwZSArIFNpdGU6VGltZVAgKyBHZW5vdHlwZTpUaW1lUCwgZGF0YT1Ub2xEYXRhKQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX1Njb3JlRl9sbSkpKQ0KDQojUS1RIHBsb3QNCnFxbm9ybShyZXNpZChUb2xfU2NvcmVGX2xtKSk7IHFxbGluZShyZXNpZChUb2xfU2NvcmVGX2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9TY29yZUZfbG0pLCByZXNpZChUb2xfU2NvcmVGX2xtKSkNCg0KYGBgDQoNClJlc2lkdWFscyBhcmUgbm90IGdyZWF0LCBuZWVkIHRvIGNoZWNrIGZvciBvdGhlciBtb2RlbGluZyBvcHRpb25zIGZvciBDb2xvciBGdWxsIFNldC4NCg0KDQojIyMgTW9kZWwgUmVzdWx0cw0KDQpgYGB7cn0NCiNNb2RlbCBSZXN1bHRzDQpzdW1tYXJ5KFRvbF9TY29yZUZfbG0pDQphbm92YShUb2xfU2NvcmVGX2xtKQ0KDQojRWZmZWN0IFNpemUgb2YgUHJlZGljdG9ycw0KZXRhX3NxdWFyZWQoVG9sX1Njb3JlRl9sbSwgcGFydGlhbD1GQUxTRSkNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9TY29yZUZfbG0ucmVzPC1kYXRhLmZyYW1lKGFub3ZhKFRvbF9TY29yZUZfbG0pKQ0KVG9sX1Njb3JlRl9sbS5yZXMkUHJlZGljdG9yPC1yb3duYW1lcyhUb2xfU2NvcmVGX2xtLnJlcykNClRvbF9TY29yZUZfbG0ucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9TY29yZUZfbG0sIHBhcnRpYWw9RkFMU0UpJEV0YTIsIE5BKQ0KVG9sX1Njb3JlRl9sbS5yZXMkUmVzcG9uc2U8LXJlcCgiQ29sb3JfRnVsbFNldCIsIG5yb3coVG9sX1Njb3JlRl9sbS5yZXMpKQ0KVG9sX1Njb3JlRl9sbS5yZXM8LVRvbF9TY29yZUZfbG0ucmVzICU+JSBkcGx5cjo6cmVuYW1lKCBwLnZhbHVlID0gIlByLi5GLiIsIERGPSAiRGYiKQ0KDQpgYGANClN0cm9uZyBpbmZsdWVuY2Ugb2YgVGltZXBvaW50LCBpbmNsdWRpbmcgaW50ZXJhY3Rpb25zIHdpdGggR2Vub3R5cGUuIFdpbGwgYW5hbHl6ZSBlYWNoIFRpbWVwb2ludCBpbmRpdmlkdWFsbHkuIA0KDQoNCiMjIENvbG9yIFNjb3JlIEZ1bGwgU2V0IFN1bW1lciAxIFRpbWVwb2ludCBXMg0KDQojIyMgUnVuIE1vZGVsDQpgYGB7cn0NCiMjQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRvbERhdGFfVzIkU2NvcmVfRnVsbC5wcm9wKQ0Kc2hhcGlyby50ZXN0KFRvbERhdGFfVzIkU2NvcmVfRnVsbC5wcm9wKQ0KI05vcm1hbA0KDQojI01vZGVsIGFzIGEgZnVuY3Rpb24gb2YgU2l0ZSBhbmQgR2Vub3R5cGUNClRvbF9TY29yZUZfVzJfbG08LWxtKFNjb3JlX0Z1bGwucHJvcH5TaXRlK0dlbm90eXBlK1NpdGU6R2Vub3R5cGUsIGRhdGE9VG9sRGF0YV9XMikNCg0KYGBgDQoNCg0KIyMjIyBDaGVjayBSZXNpZHVhbHMNCmBgYHtyfQ0KIyNDaGVjayBOb3JtYWxpdHkgb2YgUmVzaWR1YWxzDQojRGlzdHJpYnV0aW9uIA0KcGxvdChkZW5zaXR5KHJlc2lkKFRvbF9TY29yZUZfVzJfbG0pKSkNCg0KI1EtUSBwbG90DQpxcW5vcm0ocmVzaWQoVG9sX1Njb3JlRl9XMl9sbSkpOyBxcWxpbmUocmVzaWQoVG9sX1Njb3JlRl9XMl9sbSkpDQoNCiMjQ2hlY2sgVmFyaWFuY2Ugb2YgUmVzaWR1YWxzIGFjcm9zcyBGaXR0ZWQgVmFsdWVzDQpwbG90KGZpdHRlZChUb2xfU2NvcmVGX1cyX2xtKSwgcmVzaWQoVG9sX1Njb3JlRl9XMl9sbSkpDQoNCmBgYA0KDQoNCiMjIyBNb2RlbCBSZXN1bHRzDQoNCiMjIyMgT3ZlcmFsbA0KYGBge3J9DQojTW9kZWwgUmVzdWx0cw0Kc3VtbWFyeShUb2xfU2NvcmVGX1cyX2xtKQ0KYW5vdmEoVG9sX1Njb3JlRl9XMl9sbSkNCg0KI0VmZmVjdCBTaXplIG9mIFByZWRpY3RvcnMNCmV0YV9zcXVhcmVkKFRvbF9TY29yZUZfVzJfbG0sIHBhcnRpYWw9RkFMU0UpDQoNCiMjU2F2ZSBtb2RlbCByZXN1bHRzDQpUb2xfU2NvcmVGX1cyX2xtLnJlczwtZGF0YS5mcmFtZShhbm92YShUb2xfU2NvcmVGX1cyX2xtKSkNClRvbF9TY29yZUZfVzJfbG0ucmVzJFByZWRpY3Rvcjwtcm93bmFtZXMoVG9sX1Njb3JlRl9XMl9sbS5yZXMpDQpUb2xfU2NvcmVGX1cyX2xtLnJlcyRFdGFTcTwtYyhldGFfc3F1YXJlZChUb2xfU2NvcmVGX1cyX2xtLCBwYXJ0aWFsPUZBTFNFKSRFdGEyLCBOQSkNClRvbF9TY29yZUZfVzJfbG0ucmVzJFJlc3BvbnNlPC1yZXAoIkNvbG9yX0Z1bGxTZXQiLCBucm93KFRvbF9TY29yZUZfVzJfbG0ucmVzKSkNClRvbF9TY29yZUZfVzJfbG0ucmVzJFRpbWVQPC1yZXAoIlcyIiwgbnJvdyhUb2xfU2NvcmVGX1cyX2xtLnJlcykpDQpUb2xfU2NvcmVGX1cyX2xtLnJlczwtVG9sX1Njb3JlRl9XMl9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KDQpTaWduaWZpY2FudCBlZmZlY3Qgb2YgU2l0ZSBhbmQgR2Vub3R5cGUuIFN0aWxsIGNoZWNraW5nIFNpdGUqR2Vub3R5cGUgZm9yIGNvbXBhcmFiaWxpdHkgYWNyb3NzIFRpbWVwb2ludHMuDQoNCg0KDQojIyMjIFBhaXJ3aXNlDQpgYGB7cn0NCiNQYWlyd2lzZSBjb21wYXJpc29ucyBhY3Jvc3M6DQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQplbW1lYW5zKFRvbF9TY29yZUZfVzJfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNCmVtbWVhbnMoVG9sX1Njb3JlRl9XMl9sbSwgcGFpcndpc2V+U2l0ZSB8IEdlbm90eXBlKQ0KDQojI1NhdmUgcC12YWx1ZXMNCg0KI0dlbm90eXBlcyB3aXRoaW4gU2l0ZXMNClRvbF9TY29yZUZfVzJfbG0uZ2VubzwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9TY29yZUZfVzJfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkkY29udHJhc3RzKQ0KVG9sX1Njb3JlRl9XMl9sbS5nZW5vPC1Ub2xfU2NvcmVGX1cyX2xtLmdlbm8gJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfU2NvcmVGX1cyX2xtLmdlbm8kZ3JvdXAxPC1wYXN0ZShUb2xfU2NvcmVGX1cyX2xtLmdlbm8kU2l0ZSwgVG9sX1Njb3JlRl9XMl9sbS5nZW5vJGdyb3VwMSwgc2VwPSJfIikNClRvbF9TY29yZUZfVzJfbG0uZ2VubyRncm91cDI8LXBhc3RlKFRvbF9TY29yZUZfVzJfbG0uZ2VubyRTaXRlLCBUb2xfU2NvcmVGX1cyX2xtLmdlbm8kZ3JvdXAyLCBzZXA9Il8iKQ0KDQojU2l0ZXMgd2l0aGluIEdlbm90eXBlcw0KVG9sX1Njb3JlRl9XMl9sbS5zaXRlPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1Njb3JlRl9XMl9sbSwgcGFpcndpc2V+U2l0ZSB8IEdlbm90eXBlKSRjb250cmFzdHMpDQpUb2xfU2NvcmVGX1cyX2xtLnNpdGU8LVRvbF9TY29yZUZfVzJfbG0uc2l0ZSAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TY29yZUZfVzJfbG0uc2l0ZSRncm91cDE8LXBhc3RlKFRvbF9TY29yZUZfVzJfbG0uc2l0ZSRncm91cDEsIFRvbF9TY29yZUZfVzJfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNClRvbF9TY29yZUZfVzJfbG0uc2l0ZSRncm91cDI8LXBhc3RlKFRvbF9TY29yZUZfVzJfbG0uc2l0ZSRncm91cDIsIFRvbF9TY29yZUZfVzJfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNCg0KI0Z1bGwgbGlzdCBvZiBwLXZhbHVlcw0KVG9sX1Njb3JlRl9XMl9sbS5wPC1yYmluZChUb2xfU2NvcmVGX1cyX2xtLmdlbm9bLGMoMToyLDQ6OCldLCBUb2xfU2NvcmVGX1cyX2xtLnNpdGVbLGMoMToyLDQ6OCldKQ0KVG9sX1Njb3JlRl9XMl9sbS5wPC1Ub2xfU2NvcmVGX1cyX2xtLnAgJT4lIGRwbHlyOjpyZW5hbWUoIHAgPSBwLnZhbHVlKQ0KDQojQWRkIFNpZ25pZmljYW5jZSBMZXZlbHMNClRvbF9TY29yZUZfVzJfbG0ucCRTaWc8LWlmZWxzZShUb2xfU2NvcmVGX1cyX2xtLnAkcDwwLjAwMSwgIioqKiIsIGlmZWxzZShUb2xfU2NvcmVGX1cyX2xtLnAkcDwwLjAxLCAiKioiLCBpZmVsc2UoVG9sX1Njb3JlRl9XMl9sbS5wJHA8MC4wNSwgIioiLCBOQSkpKQ0KDQojU3BlY2lmeSBSZXNwb25zZSBhbmQgVGltZXBvaW50DQpUb2xfU2NvcmVGX1cyX2xtLnAkUmVzcG9uc2U8LXJlcCgiQ29sb3JfRnVsbFNldCIsIG5yb3coVG9sX1Njb3JlRl9XMl9sbS5wKSkNClRvbF9TY29yZUZfVzJfbG0ucCRUaW1lUDwtcmVwKCJXMiIsIG5yb3coVG9sX1Njb3JlRl9XMl9sbS5wKSkNCg0KYGBgDQoNCg0KIyMjIFBsb3QgUmV0ZW50aW9uIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpgYGB7cn0NCiMjU3VtbWFyeSBzdGF0aXN0aWNzIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpUb2xfU2NvcmVGX1cyX1NHPC1zdW1tYXJ5U0UoVG9sRGF0YV9XMiwgbWVhc3VyZXZhcj0iU2NvcmVfRnVsbC5wcm9wIiwgZ3JvdXB2YXJzPWMoIlNpdGUuR2VubyIsICJTaXRlIiwgIkdlbm90eXBlIiksIG5hLnJtPVRSVUUpDQoNCiMjUGxvdCBBdmVyYWdlIFJldGVudGlvbiBhY3Jvc3MgVHJlYXRtZW50cw0KVG9sX1Njb3JlRl9XMl9TRy5wbG90PC1nZ3Bsb3QoVG9sX1Njb3JlRl9XMl9TRywgYWVzKHg9U2l0ZS5HZW5vLCB5PVNjb3JlX0Z1bGwucHJvcCwgY29sb3VyPUdlbm90eXBlKSkgKyANCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1TY29yZV9GdWxsLnByb3Atc2UsIHltYXg9U2NvcmVfRnVsbC5wcm9wK3NlKSwgd2lkdGg9Y2FwLnN6LCBsaW5ld2lkdGg9YmFyLnN6KSsNCiAgZ2VvbV9wb2ludChzaXplPXBvaW50LnN6KSsgDQogICBnZ3RpdGxlKCJDb2xvciBSZXRlbnRpb24gRnVsbCBTZXQiKSsNCiAgdGhlbWVfY2xhc3NpYygpKw0KICB0aGVtZSggYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLA0KICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsIA0KICAgICAgICBsZWdlbmQuZGlyZWN0aW9uPSJob3Jpem9udGFsIiwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gcGxvdC50aXRsZS5zeiwgY29sb3VyPSJibGFjayIsIGhqdXN0ID0gMC41KSkrDQogIGxhYnMoeD0iIiwgeT0iUHJvcG9ydGlvbiBSZXRhaW5lZCIpKw0KICB5bGltKDAsIDEuNSkrIA0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIiLCJLbGVpbiIsIiIsIiIsIlNvbWV0aGluZyBTcGVjaWFsIiwiIikpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gR2Vuby5jb2xvcnMubykrIA0KICBzdGF0X3B2YWx1ZV9tYW51YWwoZGF0YT1Ub2xfU2NvcmVGX1cyX2xtLnAsICB5LnBvc2l0aW9uPTAuOSwgc3RlcC5pbmNyZWFzZT0wLjM1LCBsYWJlbD0iU2lnIiwgaGlkZS5ucz1UUlVFKTsgVG9sX1Njb3JlRl9XMl9TRy5wbG90DQoNCmBgYA0KDQoNCiMjIENvbG9yIFNjb3JlIEZ1bGwgU2V0IFN1bW1lciAyIFRpbWVwb2ludCBNMQ0KDQojIyMgUnVuIE1vZGVsDQpgYGB7cn0NCiMjQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRvbERhdGFfTTEkU2NvcmVfRnVsbC5wcm9wKQ0Kc2hhcGlyby50ZXN0KFRvbERhdGFfTTEkU2NvcmVfRnVsbC5wcm9wKQ0KI05vdCBub3JtYWwNCg0KIyNUcnkgc3F1YXJlIHRyYW5zZm9ybWF0aW9uDQpoaXN0KChUb2xEYXRhX00xJFNjb3JlX0Z1bGwucHJvcCleMikNCnNoYXBpcm8udGVzdCgoVG9sRGF0YV9NMSRTY29yZV9GdWxsLnByb3ApXjIpDQojTm90IG5vcm1hbA0KDQojI1RyeSBjdWJlZCB0cmFuc2Zvcm1hdGlvbg0KaGlzdCgoVG9sRGF0YV9NMSRTY29yZV9GdWxsLnByb3ApXjMpDQpzaGFwaXJvLnRlc3QoKFRvbERhdGFfTTEkU2NvcmVfRnVsbC5wcm9wKV4zKQ0KI05vdCBub3JtYWwNCg0KIyNNb2RlbCBhcyBhIGZ1bmN0aW9uIG9mIFNpdGUgYW5kIEdlbm90eXBlDQojI01vZGVsIHdpdGggbm8gdHJhbnNmb3JtYXRpb24gYW5kIGNoZWNrIHJlc2lkdWFscw0KVG9sX1Njb3JlRl9NMV9sbTwtbG0oU2NvcmVfRnVsbC5wcm9wflNpdGUrR2Vub3R5cGUrU2l0ZTpHZW5vdHlwZSwgZGF0YT1Ub2xEYXRhX00xKQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX1Njb3JlRl9NMV9sbSkpKQ0KDQojUS1RIHBsb3QNCnFxbm9ybShyZXNpZChUb2xfU2NvcmVGX00xX2xtKSk7IHFxbGluZShyZXNpZChUb2xfU2NvcmVGX00xX2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9TY29yZUZfTTFfbG0pLCByZXNpZChUb2xfU2NvcmVGX00xX2xtKSkNCg0KYGBgDQoNCg0KIyMjIE1vZGVsIFJlc3VsdHMNCg0KIyMjIyBPdmVyYWxsDQpgYGB7cn0NCiNNb2RlbCBSZXN1bHRzDQpzdW1tYXJ5KFRvbF9TY29yZUZfTTFfbG0pDQphbm92YShUb2xfU2NvcmVGX00xX2xtKQ0KDQojRWZmZWN0IFNpemUgb2YgUHJlZGljdG9ycw0KZXRhX3NxdWFyZWQoVG9sX1Njb3JlRl9NMV9sbSwgcGFydGlhbD1GQUxTRSkNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9TY29yZUZfTTFfbG0ucmVzPC1kYXRhLmZyYW1lKGFub3ZhKFRvbF9TY29yZUZfTTFfbG0pKQ0KVG9sX1Njb3JlRl9NMV9sbS5yZXMkUHJlZGljdG9yPC1yb3duYW1lcyhUb2xfU2NvcmVGX00xX2xtLnJlcykNClRvbF9TY29yZUZfTTFfbG0ucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9TY29yZUZfTTFfbG0sIHBhcnRpYWw9RkFMU0UpJEV0YTIsIE5BKQ0KVG9sX1Njb3JlRl9NMV9sbS5yZXMkUmVzcG9uc2U8LXJlcCgiQ29sb3JfRnVsbFNldCIsIG5yb3coVG9sX1Njb3JlRl9NMV9sbS5yZXMpKQ0KVG9sX1Njb3JlRl9NMV9sbS5yZXMkVGltZVA8LXJlcCgiTTEiLCBucm93KFRvbF9TY29yZUZfTTFfbG0ucmVzKSkNClRvbF9TY29yZUZfTTFfbG0ucmVzPC1Ub2xfU2NvcmVGX00xX2xtLnJlcyAlPiUgZHBseXI6OnJlbmFtZSggcC52YWx1ZSA9ICJQci4uRi4iLCBERj0gIkRmIikNCg0KYGBgDQoNClNpZ25pZmljYW50IGVmZmVjdCBvZiBTaXRlIGFuZCBHZW5vdHlwZS4gU3RpbGwgY2hlY2tpbmcgU2l0ZSpHZW5vdHlwZSBmb3IgY29tcGFyYWJpbGl0eSBhY3Jvc3MgVGltZXBvaW50cy4NCg0KDQojIyMjIFBhaXJ3aXNlDQpgYGB7cn0NCiNQYWlyd2lzZSBjb21wYXJpc29ucyBhY3Jvc3M6DQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQplbW1lYW5zKFRvbF9TY29yZUZfTTFfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNCmVtbWVhbnMoVG9sX1Njb3JlRl9NMV9sbSwgcGFpcndpc2V+U2l0ZSB8IEdlbm90eXBlKQ0KDQojI1NhdmUgcC12YWx1ZXMNCg0KI0dlbm90eXBlcyB3aXRoaW4gU2l0ZXMNClRvbF9TY29yZUZfTTFfbG0uZ2VubzwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9TY29yZUZfTTFfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkkY29udHJhc3RzKQ0KVG9sX1Njb3JlRl9NMV9sbS5nZW5vPC1Ub2xfU2NvcmVGX00xX2xtLmdlbm8gJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfU2NvcmVGX00xX2xtLmdlbm8kZ3JvdXAxPC1wYXN0ZShUb2xfU2NvcmVGX00xX2xtLmdlbm8kU2l0ZSwgVG9sX1Njb3JlRl9NMV9sbS5nZW5vJGdyb3VwMSwgc2VwPSJfIikNClRvbF9TY29yZUZfTTFfbG0uZ2VubyRncm91cDI8LXBhc3RlKFRvbF9TY29yZUZfTTFfbG0uZ2VubyRTaXRlLCBUb2xfU2NvcmVGX00xX2xtLmdlbm8kZ3JvdXAyLCBzZXA9Il8iKQ0KDQojU2l0ZXMgd2l0aGluIEdlbm90eXBlcw0KVG9sX1Njb3JlRl9NMV9sbS5zaXRlPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1Njb3JlRl9NMV9sbSwgcGFpcndpc2V+U2l0ZSB8IEdlbm90eXBlKSRjb250cmFzdHMpDQpUb2xfU2NvcmVGX00xX2xtLnNpdGU8LVRvbF9TY29yZUZfTTFfbG0uc2l0ZSAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TY29yZUZfTTFfbG0uc2l0ZSRncm91cDE8LXBhc3RlKFRvbF9TY29yZUZfTTFfbG0uc2l0ZSRncm91cDEsIFRvbF9TY29yZUZfTTFfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNClRvbF9TY29yZUZfTTFfbG0uc2l0ZSRncm91cDI8LXBhc3RlKFRvbF9TY29yZUZfTTFfbG0uc2l0ZSRncm91cDIsIFRvbF9TY29yZUZfTTFfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNCg0KI0Z1bGwgbGlzdCBvZiBwLXZhbHVlcw0KVG9sX1Njb3JlRl9NMV9sbS5wPC1yYmluZChUb2xfU2NvcmVGX00xX2xtLmdlbm9bLGMoMToyLDQ6OCldLCBUb2xfU2NvcmVGX00xX2xtLnNpdGVbLGMoMToyLDQ6OCldKQ0KVG9sX1Njb3JlRl9NMV9sbS5wPC1Ub2xfU2NvcmVGX00xX2xtLnAgJT4lIGRwbHlyOjpyZW5hbWUoIHAgPSBwLnZhbHVlKQ0KDQojQWRkIFNpZ25pZmljYW5jZSBMZXZlbHMNClRvbF9TY29yZUZfTTFfbG0ucCRTaWc8LWlmZWxzZShUb2xfU2NvcmVGX00xX2xtLnAkcDwwLjAwMSwgIioqKiIsIGlmZWxzZShUb2xfU2NvcmVGX00xX2xtLnAkcDwwLjAxLCAiKioiLCBpZmVsc2UoVG9sX1Njb3JlRl9NMV9sbS5wJHA8MC4wNSwgIioiLCBOQSkpKQ0KDQojU3BlY2lmeSBSZXNwb25zZSBhbmQgVGltZXBvaW50DQpUb2xfU2NvcmVGX00xX2xtLnAkUmVzcG9uc2U8LXJlcCgiQ29sb3JfRnVsbFNldCIsIG5yb3coVG9sX1Njb3JlRl9NMV9sbS5wKSkNClRvbF9TY29yZUZfTTFfbG0ucCRUaW1lUDwtcmVwKCJNMSIsIG5yb3coVG9sX1Njb3JlRl9NMV9sbS5wKSkNCg0KYGBgDQoNCg0KIyMjIFBsb3QgUmV0ZW50aW9uIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpgYGB7cn0NCiMjU3VtbWFyeSBzdGF0aXN0aWNzIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpUb2xfU2NvcmVGX00xX1NHPC1zdW1tYXJ5U0UoVG9sRGF0YV9NMSwgbWVhc3VyZXZhcj0iU2NvcmVfRnVsbC5wcm9wIiwgZ3JvdXB2YXJzPWMoIlNpdGUuR2VubyIsICJTaXRlIiwgIkdlbm90eXBlIiksIG5hLnJtPVRSVUUpDQoNCiMjUGxvdCBBdmVyYWdlIFJldGVudGlvbiBhY3Jvc3MgVHJlYXRtZW50cw0KVG9sX1Njb3JlRl9NMV9TRy5wbG90PC1nZ3Bsb3QoVG9sX1Njb3JlRl9NMV9TRywgYWVzKHg9U2l0ZS5HZW5vLCB5PVNjb3JlX0Z1bGwucHJvcCwgY29sb3VyPUdlbm90eXBlKSkgKyANCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1TY29yZV9GdWxsLnByb3Atc2UsIHltYXg9U2NvcmVfRnVsbC5wcm9wK3NlKSwgd2lkdGg9Y2FwLnN6LCBsaW5ld2lkdGg9YmFyLnN6KSsNCiAgZ2VvbV9wb2ludChzaXplPXBvaW50LnN6KSsgDQogICBnZ3RpdGxlKCJDb2xvciBSZXRlbnRpb24gRnVsbCBTZXQiKSsNCiAgdGhlbWVfY2xhc3NpYygpKw0KICB0aGVtZSggYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLA0KICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsIA0KICAgICAgICBsZWdlbmQuZGlyZWN0aW9uPSJob3Jpem9udGFsIiwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gcGxvdC50aXRsZS5zeiwgY29sb3VyPSJibGFjayIsIGhqdXN0ID0gMC41KSkrDQogIGxhYnMoeD0iIiwgeT0iUHJvcG9ydGlvbiBSZXRhaW5lZCIpKw0KIHlsaW0oMCwgMS41KSsgDQogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIiIsIktsZWluIiwiIiwiIiwiU29tZXRoaW5nIFNwZWNpYWwiLCIiKSkrDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBHZW5vLmNvbG9ycy5vKSsgDQogIHN0YXRfcHZhbHVlX21hbnVhbChkYXRhPVRvbF9TY29yZUZfTTFfbG0ucCwgIHkucG9zaXRpb249MS4xLCBzdGVwLmluY3JlYXNlPTAuMiwgbGFiZWw9IlNpZyIsIGhpZGUubnM9VFJVRSk7IFRvbF9TY29yZUZfTTFfU0cucGxvdA0KDQpgYGANCg0KDQojIyBDb2xvciBTY29yZSBGdWxsIFNldCBXaW50ZXIgVGltZXBvaW50IE00DQoNCiMjIyBSdW4gTW9kZWwNCmBgYHtyfQ0KIyNDaGVjayBub3JtYWxpdHkNCmhpc3QoVG9sRGF0YV9NNCRTY29yZV9GdWxsLnByb3ApDQpzaGFwaXJvLnRlc3QoVG9sRGF0YV9NNCRTY29yZV9GdWxsLnByb3ApDQojTm90IE5vcm1hbA0KDQojI1RyeSBzcXVhcmUgdHJhbnNmb3JtYXRpb24NCmhpc3QoKFRvbERhdGFfTTQkU2NvcmVfRnVsbC5wcm9wKV4yKQ0Kc2hhcGlyby50ZXN0KChUb2xEYXRhX000JFNjb3JlX0Z1bGwucHJvcCleMikNCiNOb3QgTm9ybWFsDQoNCiMjVHJ5IGN1YmVkIHRyYW5zZm9ybWF0aW9uDQpoaXN0KChUb2xEYXRhX000JFNjb3JlX0Z1bGwucHJvcCleMykNCnNoYXBpcm8udGVzdCgoVG9sRGF0YV9NNCRTY29yZV9GdWxsLnByb3ApXjMpDQojTm90IE5vcm1hbA0KDQojI01vZGVsIGFzIGEgZnVuY3Rpb24gb2YgU2l0ZSBhbmQgR2Vub3R5cGUNCiMjTW9kZWwgd2l0aCBubyB0cmFuc2Zvcm1hdGlvbiBhbmQgY2hlY2sgcmVzaWR1YWxzDQpUb2xfU2NvcmVGX000X2xtPC1sbShTY29yZV9GdWxsLnByb3B+U2l0ZStHZW5vdHlwZStTaXRlOkdlbm90eXBlLCBkYXRhPVRvbERhdGFfTTQpDQoNCmBgYA0KDQoNCiMjIyMgQ2hlY2sgUmVzaWR1YWxzDQpgYGB7cn0NCiMjQ2hlY2sgTm9ybWFsaXR5IG9mIFJlc2lkdWFscw0KI0Rpc3RyaWJ1dGlvbiANCnBsb3QoZGVuc2l0eShyZXNpZChUb2xfU2NvcmVGX000X2xtKSkpDQoNCiNRLVEgcGxvdA0KcXFub3JtKHJlc2lkKFRvbF9TY29yZUZfTTRfbG0pKTsgcXFsaW5lKHJlc2lkKFRvbF9TY29yZUZfTTRfbG0pKQ0KDQojI0NoZWNrIFZhcmlhbmNlIG9mIFJlc2lkdWFscyBhY3Jvc3MgRml0dGVkIFZhbHVlcw0KcGxvdChmaXR0ZWQoVG9sX1Njb3JlRl9NNF9sbSksIHJlc2lkKFRvbF9TY29yZUZfTTRfbG0pKQ0KDQpgYGANCg0KDQojIyMgTW9kZWwgUmVzdWx0cw0KDQojIyMjIE92ZXJhbGwNCmBgYHtyfQ0KI01vZGVsIFJlc3VsdHMNCnN1bW1hcnkoVG9sX1Njb3JlRl9NNF9sbSkNCmFub3ZhKFRvbF9TY29yZUZfTTRfbG0pDQoNCiNFZmZlY3QgU2l6ZSBvZiBQcmVkaWN0b3JzDQpldGFfc3F1YXJlZChUb2xfU2NvcmVGX000X2xtLCBwYXJ0aWFsPUZBTFNFKQ0KDQojI1NhdmUgbW9kZWwgcmVzdWx0cw0KVG9sX1Njb3JlRl9NNF9sbS5yZXM8LWRhdGEuZnJhbWUoYW5vdmEoVG9sX1Njb3JlRl9NNF9sbSkpDQpUb2xfU2NvcmVGX000X2xtLnJlcyRQcmVkaWN0b3I8LXJvd25hbWVzKFRvbF9TY29yZUZfTTRfbG0ucmVzKQ0KVG9sX1Njb3JlRl9NNF9sbS5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoVG9sX1Njb3JlRl9NNF9sbSwgcGFydGlhbD1GQUxTRSkkRXRhMiwgTkEpDQpUb2xfU2NvcmVGX000X2xtLnJlcyRSZXNwb25zZTwtcmVwKCJDb2xvcl9GdWxsU2V0IiwgbnJvdyhUb2xfU2NvcmVGX000X2xtLnJlcykpDQpUb2xfU2NvcmVGX000X2xtLnJlcyRUaW1lUDwtcmVwKCJNNCIsIG5yb3coVG9sX1Njb3JlRl9NNF9sbS5yZXMpKQ0KVG9sX1Njb3JlRl9NNF9sbS5yZXM8LVRvbF9TY29yZUZfTTRfbG0ucmVzICU+JSBkcGx5cjo6cmVuYW1lKCBwLnZhbHVlID0gIlByLi5GLiIsIERGPSAiRGYiKQ0KDQpgYGANCg0KU2lnbmlmaWNhbnQgZWZmZWN0IG9mIFNpdGUgYW5kIEdlbm90eXBlLiBTdGlsbCBjaGVja2luZyBTaXRlKkdlbm90eXBlIGZvciBjb21wYXJhYmlsaXR5IGFjcm9zcyBUaW1lcG9pbnRzLg0KDQoNCg0KIyMjIyBQYWlyd2lzZQ0KYGBge3J9DQojUGFpcndpc2UgY29tcGFyaXNvbnMgYWNyb3NzOg0KDQojR2Vub3R5cGVzIHdpdGhpbiBTaXRlcw0KZW1tZWFucyhUb2xfU2NvcmVGX000X2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQplbW1lYW5zKFRvbF9TY29yZUZfTTRfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkNCg0KIyNTYXZlIHAtdmFsdWVzDQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQpUb2xfU2NvcmVGX000X2xtLmdlbm88LWRhdGEuZnJhbWUoZW1tZWFucyhUb2xfU2NvcmVGX000X2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpJGNvbnRyYXN0cykNClRvbF9TY29yZUZfTTRfbG0uZ2VubzwtVG9sX1Njb3JlRl9NNF9sbS5nZW5vICU+JSBzZXBhcmF0ZShjb2w9Y29udHJhc3QsIGludG89YygiZ3JvdXAxIiwgImdyb3VwMiIpLCBzZXA9IiAtICIsIHJlbW92ZT1UUlVFKQ0KVG9sX1Njb3JlRl9NNF9sbS5nZW5vJGdyb3VwMTwtcGFzdGUoVG9sX1Njb3JlRl9NNF9sbS5nZW5vJFNpdGUsIFRvbF9TY29yZUZfTTRfbG0uZ2VubyRncm91cDEsIHNlcD0iXyIpDQpUb2xfU2NvcmVGX000X2xtLmdlbm8kZ3JvdXAyPC1wYXN0ZShUb2xfU2NvcmVGX000X2xtLmdlbm8kU2l0ZSwgVG9sX1Njb3JlRl9NNF9sbS5nZW5vJGdyb3VwMiwgc2VwPSJfIikNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNClRvbF9TY29yZUZfTTRfbG0uc2l0ZTwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9TY29yZUZfTTRfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkkY29udHJhc3RzKQ0KVG9sX1Njb3JlRl9NNF9sbS5zaXRlPC1Ub2xfU2NvcmVGX000X2xtLnNpdGUgJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfU2NvcmVGX000X2xtLnNpdGUkZ3JvdXAxPC1wYXN0ZShUb2xfU2NvcmVGX000X2xtLnNpdGUkZ3JvdXAxLCBUb2xfU2NvcmVGX000X2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQpUb2xfU2NvcmVGX000X2xtLnNpdGUkZ3JvdXAyPC1wYXN0ZShUb2xfU2NvcmVGX000X2xtLnNpdGUkZ3JvdXAyLCBUb2xfU2NvcmVGX000X2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQoNCiNGdWxsIGxpc3Qgb2YgcC12YWx1ZXMNClRvbF9TY29yZUZfTTRfbG0ucDwtcmJpbmQoVG9sX1Njb3JlRl9NNF9sbS5nZW5vWyxjKDE6Miw0OjgpXSwgVG9sX1Njb3JlRl9NNF9sbS5zaXRlWyxjKDE6Miw0OjgpXSkNClRvbF9TY29yZUZfTTRfbG0ucDwtVG9sX1Njb3JlRl9NNF9sbS5wICU+JSBkcGx5cjo6cmVuYW1lKCBwID0gcC52YWx1ZSkNCg0KI0FkZCBTaWduaWZpY2FuY2UgTGV2ZWxzDQpUb2xfU2NvcmVGX000X2xtLnAkU2lnPC1pZmVsc2UoVG9sX1Njb3JlRl9NNF9sbS5wJHA8MC4wMDEsICIqKioiLCBpZmVsc2UoVG9sX1Njb3JlRl9NNF9sbS5wJHA8MC4wMSwgIioqIiwgaWZlbHNlKFRvbF9TY29yZUZfTTRfbG0ucCRwPDAuMDUsICIqIiwgTkEpKSkNCg0KI1NwZWNpZnkgUmVzcG9uc2UgYW5kIFRpbWVwb2ludA0KVG9sX1Njb3JlRl9NNF9sbS5wJFJlc3BvbnNlPC1yZXAoIkNvbG9yX0Z1bGxTZXQiLCBucm93KFRvbF9TY29yZUZfTTRfbG0ucCkpDQpUb2xfU2NvcmVGX000X2xtLnAkVGltZVA8LXJlcCgiTTQiLCBucm93KFRvbF9TY29yZUZfTTRfbG0ucCkpDQoNCmBgYA0KDQoNCiMjIyBQbG90IFJldGVudGlvbiBieSBTaXRlIGFuZCBHZW5vdHlwZQ0KYGBge3J9DQojI1N1bW1hcnkgc3RhdGlzdGljcyBieSBTaXRlIGFuZCBHZW5vdHlwZQ0KVG9sX1Njb3JlRl9NNF9TRzwtc3VtbWFyeVNFKFRvbERhdGFfTTQsIG1lYXN1cmV2YXI9IlNjb3JlX0Z1bGwucHJvcCIsIGdyb3VwdmFycz1jKCJTaXRlLkdlbm8iLCAiU2l0ZSIsICJHZW5vdHlwZSIpLCBuYS5ybT1UUlVFKQ0KDQojI1Bsb3QgQXZlcmFnZSBSZXRlbnRpb24gYWNyb3NzIFRyZWF0bWVudHMNClRvbF9TY29yZUZfTTRfU0cucGxvdDwtZ2dwbG90KFRvbF9TY29yZUZfTTRfU0csIGFlcyh4PVNpdGUuR2VubywgeT1TY29yZV9GdWxsLnByb3AsIGNvbG91cj1HZW5vdHlwZSkpICsgDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49U2NvcmVfRnVsbC5wcm9wLXNlLCB5bWF4PVNjb3JlX0Z1bGwucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeikrDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeikrIA0KICAgZ2d0aXRsZSgiQ29sb3IgUmV0ZW50aW9uIEZ1bGwgU2V0IikrDQogIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCANCiAgICAgICAgbGVnZW5kLmRpcmVjdGlvbj0iaG9yaXpvbnRhbCIsDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IlByb3BvcnRpb24gUmV0YWluZWQiKSsNCiAgeWxpbSgwLCAxLjUpKyANCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiIiwiS2xlaW4iLCIiLCIiLCJTb21ldGhpbmcgU3BlY2lhbCIsIiIpKSsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IEdlbm8uY29sb3JzLm8pKyANCiAgc3RhdF9wdmFsdWVfbWFudWFsKGRhdGE9VG9sX1Njb3JlRl9NNF9sbS5wLCAgeS5wb3NpdGlvbj0xLjEsIHN0ZXAuaW5jcmVhc2U9MC4yMiwgbGFiZWw9IlNpZyIsIGhpZGUubnM9VFJVRSk7IFRvbF9TY29yZUZfTTRfU0cucGxvdA0KDQpgYGANCg0KDQojIFRoZXJtYWwgVG9sZXJhbmNlIENvbG9yIGJ5IFRpbWVwb2ludA0KDQojIyBGdWxsIFNldA0KDQojIyMgUnVuIE1vZGVsDQpgYGB7cn0NCiMjQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRvbERhdGEkU2NvcmVfVFAucHJvcCkNCnNoYXBpcm8udGVzdChUb2xEYXRhJFNjb3JlX1RQLnByb3ApDQojTm90IE5vcm1hbA0KDQojI1RyeSBzcXVhcmUgdHJhbnNmb3JtYXRpb24NCmhpc3QoKFRvbERhdGEkU2NvcmVfVFAucHJvcCleMikNCnNoYXBpcm8udGVzdCgoVG9sRGF0YSRTY29yZV9UUC5wcm9wKV4yKQ0KI05vdCBub3JtYWwgDQoNCiMjVHJ5IGN1YmVkIHRyYW5zZm9ybWF0aW9uDQpoaXN0KChUb2xEYXRhJFNjb3JlX1RQLnByb3ApXjMpDQpzaGFwaXJvLnRlc3QoKFRvbERhdGEkU2NvcmVfVFAucHJvcCleMykNCiNOb3Qgbm9ybWFsIA0KDQoNCiMjTW9kZWwgYXMgYSBmdW5jdGlvbiBvZiBTaXRlIGFuZCBHZW5vdHlwZSBhbmQgVGltZXBvaW50DQojI01vZGVsIHdpdGggbm8gdHJhbnNmb3JtYXRpb24gYW5kIGNoZWNrIHJlc2lkdWFscw0KVG9sX1Njb3JlVFBfbG08LWxtKFNjb3JlX1RQLnByb3B+U2l0ZStHZW5vdHlwZStUaW1lUCsgU2l0ZTpHZW5vdHlwZSArIFNpdGU6VGltZVAgKyBHZW5vdHlwZTpUaW1lUCwgZGF0YT1Ub2xEYXRhKQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX1Njb3JlVFBfbG0pKSkNCg0KI1EtUSBwbG90DQpxcW5vcm0ocmVzaWQoVG9sX1Njb3JlVFBfbG0pKTsgcXFsaW5lKHJlc2lkKFRvbF9TY29yZVRQX2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9TY29yZVRQX2xtKSwgcmVzaWQoVG9sX1Njb3JlVFBfbG0pKQ0KDQpgYGANCg0KUmVzaWR1YWxzIGFyZSBub3QgZ3JlYXQsIG5lZWQgdG8gY2hlY2sgZm9yIG90aGVyIG1vZGVsaW5nIG9wdGlvbnMgZm9yIENvbG9yIGJ5IFRpbWVwb2ludC4NCg0KDQojIyMgTW9kZWwgUmVzdWx0cw0KDQpgYGB7cn0NCiNNb2RlbCBSZXN1bHRzDQpzdW1tYXJ5KFRvbF9TY29yZVRQX2xtKQ0KYW5vdmEoVG9sX1Njb3JlVFBfbG0pDQoNCiNFZmZlY3QgU2l6ZSBvZiBQcmVkaWN0b3JzDQpldGFfc3F1YXJlZChUb2xfU2NvcmVUUF9sbSwgcGFydGlhbD1GQUxTRSkNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9TY29yZVRQX2xtLnJlczwtZGF0YS5mcmFtZShhbm92YShUb2xfU2NvcmVUUF9sbSkpDQpUb2xfU2NvcmVUUF9sbS5yZXMkUHJlZGljdG9yPC1yb3duYW1lcyhUb2xfU2NvcmVUUF9sbS5yZXMpDQpUb2xfU2NvcmVUUF9sbS5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoVG9sX1Njb3JlVFBfbG0sIHBhcnRpYWw9RkFMU0UpJEV0YTIsIE5BKQ0KVG9sX1Njb3JlVFBfbG0ucmVzJFJlc3BvbnNlPC1yZXAoIkNvbG9yX1RQIiwgbnJvdyhUb2xfU2NvcmVUUF9sbS5yZXMpKQ0KVG9sX1Njb3JlVFBfbG0ucmVzPC1Ub2xfU2NvcmVUUF9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KU3Ryb25nIGluZmx1ZW5jZSBvZiBUaW1lcG9pbnQsIGluY2x1ZGluZyBpbnRlcmFjdGlvbnMgd2l0aCB2YXJpYWJsZXMgb2YgaW50ZXJlc3QsIFNpdGUgYW5kIEdlbm90eXBlLiBXaWxsIGFuYWx5emUgZWFjaCBUaW1lcG9pbnQgaW5kaXZpZHVhbGx5LiANCg0KDQojIyBDb2xvciBTY29yZSBieSBUaW1lcG9pbnQgU3VtbWVyIDEgVGltZXBvaW50IFcyDQoNCiMjIyBSdW4gTW9kZWwNCmBgYHtyfQ0KIyNDaGVjayBub3JtYWxpdHkNCmhpc3QoVG9sRGF0YV9XMiRTY29yZV9UUC5wcm9wKQ0Kc2hhcGlyby50ZXN0KFRvbERhdGFfVzIkU2NvcmVfVFAucHJvcCkNCiNOb3JtYWwNCg0KIyNNb2RlbCBhcyBhIGZ1bmN0aW9uIG9mIFNpdGUgYW5kIEdlbm90eXBlDQpUb2xfU2NvcmVUUF9XMl9sbTwtbG0oU2NvcmVfVFAucHJvcH5TaXRlK0dlbm90eXBlK1NpdGU6R2Vub3R5cGUsIGRhdGE9VG9sRGF0YV9XMikNCg0KYGBgDQoNCg0KIyMjIyBDaGVjayBSZXNpZHVhbHMNCmBgYHtyfQ0KIyNDaGVjayBOb3JtYWxpdHkgb2YgUmVzaWR1YWxzDQojRGlzdHJpYnV0aW9uIA0KcGxvdChkZW5zaXR5KHJlc2lkKFRvbF9TY29yZVRQX1cyX2xtKSkpDQoNCiNRLVEgcGxvdA0KcXFub3JtKHJlc2lkKFRvbF9TY29yZVRQX1cyX2xtKSk7IHFxbGluZShyZXNpZChUb2xfU2NvcmVUUF9XMl9sbSkpDQoNCiMjQ2hlY2sgVmFyaWFuY2Ugb2YgUmVzaWR1YWxzIGFjcm9zcyBGaXR0ZWQgVmFsdWVzDQpwbG90KGZpdHRlZChUb2xfU2NvcmVUUF9XMl9sbSksIHJlc2lkKFRvbF9TY29yZVRQX1cyX2xtKSkNCg0KYGBgDQoNCg0KIyMjIE1vZGVsIFJlc3VsdHMNCg0KIyMjIyBPdmVyYWxsDQpgYGB7cn0NCiNNb2RlbCBSZXN1bHRzDQpzdW1tYXJ5KFRvbF9TY29yZVRQX1cyX2xtKQ0KYW5vdmEoVG9sX1Njb3JlVFBfVzJfbG0pDQoNCiNFZmZlY3QgU2l6ZSBvZiBQcmVkaWN0b3JzDQpldGFfc3F1YXJlZChUb2xfU2NvcmVUUF9XMl9sbSwgcGFydGlhbD1GQUxTRSkNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9TY29yZVRQX1cyX2xtLnJlczwtZGF0YS5mcmFtZShhbm92YShUb2xfU2NvcmVUUF9XMl9sbSkpDQpUb2xfU2NvcmVUUF9XMl9sbS5yZXMkUHJlZGljdG9yPC1yb3duYW1lcyhUb2xfU2NvcmVUUF9XMl9sbS5yZXMpDQpUb2xfU2NvcmVUUF9XMl9sbS5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoVG9sX1Njb3JlVFBfVzJfbG0sIHBhcnRpYWw9RkFMU0UpJEV0YTIsIE5BKQ0KVG9sX1Njb3JlVFBfVzJfbG0ucmVzJFJlc3BvbnNlPC1yZXAoIkNvbG9yX1RQIiwgbnJvdyhUb2xfU2NvcmVUUF9XMl9sbS5yZXMpKQ0KVG9sX1Njb3JlVFBfVzJfbG0ucmVzJFRpbWVQPC1yZXAoIlcyIiwgbnJvdyhUb2xfU2NvcmVUUF9XMl9sbS5yZXMpKQ0KVG9sX1Njb3JlVFBfVzJfbG0ucmVzPC1Ub2xfU2NvcmVUUF9XMl9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KDQpTaWduaWZpY2FudCBlZmZlY3Qgb2YgU2l0ZSBhbmQgR2Vub3R5cGUuIFN0aWxsIGNoZWNraW5nIFNpdGUqR2Vub3R5cGUgZm9yIGNvbXBhcmFiaWxpdHkgYWNyb3NzIFRpbWVwb2ludHMuDQoNCg0KDQojIyMjIFBhaXJ3aXNlDQpgYGB7cn0NCiNQYWlyd2lzZSBjb21wYXJpc29ucyBhY3Jvc3M6DQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQplbW1lYW5zKFRvbF9TY29yZVRQX1cyX2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQplbW1lYW5zKFRvbF9TY29yZVRQX1cyX2xtLCBwYWlyd2lzZX5TaXRlIHwgR2Vub3R5cGUpDQoNCiMjU2F2ZSBwLXZhbHVlcw0KDQojR2Vub3R5cGVzIHdpdGhpbiBTaXRlcw0KVG9sX1Njb3JlVFBfVzJfbG0uZ2VubzwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9TY29yZVRQX1cyX2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpJGNvbnRyYXN0cykNClRvbF9TY29yZVRQX1cyX2xtLmdlbm88LVRvbF9TY29yZVRQX1cyX2xtLmdlbm8gJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfU2NvcmVUUF9XMl9sbS5nZW5vJGdyb3VwMTwtcGFzdGUoVG9sX1Njb3JlVFBfVzJfbG0uZ2VubyRTaXRlLCBUb2xfU2NvcmVUUF9XMl9sbS5nZW5vJGdyb3VwMSwgc2VwPSJfIikNClRvbF9TY29yZVRQX1cyX2xtLmdlbm8kZ3JvdXAyPC1wYXN0ZShUb2xfU2NvcmVUUF9XMl9sbS5nZW5vJFNpdGUsIFRvbF9TY29yZVRQX1cyX2xtLmdlbm8kZ3JvdXAyLCBzZXA9Il8iKQ0KDQojU2l0ZXMgd2l0aGluIEdlbm90eXBlcw0KVG9sX1Njb3JlVFBfVzJfbG0uc2l0ZTwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9TY29yZVRQX1cyX2xtLCBwYWlyd2lzZX5TaXRlIHwgR2Vub3R5cGUpJGNvbnRyYXN0cykNClRvbF9TY29yZVRQX1cyX2xtLnNpdGU8LVRvbF9TY29yZVRQX1cyX2xtLnNpdGUgJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfU2NvcmVUUF9XMl9sbS5zaXRlJGdyb3VwMTwtcGFzdGUoVG9sX1Njb3JlVFBfVzJfbG0uc2l0ZSRncm91cDEsIFRvbF9TY29yZVRQX1cyX2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQpUb2xfU2NvcmVUUF9XMl9sbS5zaXRlJGdyb3VwMjwtcGFzdGUoVG9sX1Njb3JlVFBfVzJfbG0uc2l0ZSRncm91cDIsIFRvbF9TY29yZVRQX1cyX2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQoNCiNGdWxsIGxpc3Qgb2YgcC12YWx1ZXMNClRvbF9TY29yZVRQX1cyX2xtLnA8LXJiaW5kKFRvbF9TY29yZVRQX1cyX2xtLmdlbm9bLGMoMToyLDQ6OCldLCBUb2xfU2NvcmVUUF9XMl9sbS5zaXRlWyxjKDE6Miw0OjgpXSkNClRvbF9TY29yZVRQX1cyX2xtLnA8LVRvbF9TY29yZVRQX1cyX2xtLnAgJT4lIGRwbHlyOjpyZW5hbWUoIHAgPSBwLnZhbHVlKQ0KDQojQWRkIFNpZ25pZmljYW5jZSBMZXZlbHMNClRvbF9TY29yZVRQX1cyX2xtLnAkU2lnPC1pZmVsc2UoVG9sX1Njb3JlVFBfVzJfbG0ucCRwPDAuMDAxLCAiKioqIiwgaWZlbHNlKFRvbF9TY29yZVRQX1cyX2xtLnAkcDwwLjAxLCAiKioiLCBpZmVsc2UoVG9sX1Njb3JlVFBfVzJfbG0ucCRwPDAuMDUsICIqIiwgTkEpKSkNCg0KI1NwZWNpZnkgUmVzcG9uc2UgYW5kIFRpbWVwb2ludA0KVG9sX1Njb3JlVFBfVzJfbG0ucCRSZXNwb25zZTwtcmVwKCJDb2xvcl9UUCIsIG5yb3coVG9sX1Njb3JlVFBfVzJfbG0ucCkpDQpUb2xfU2NvcmVUUF9XMl9sbS5wJFRpbWVQPC1yZXAoIlcyIiwgbnJvdyhUb2xfU2NvcmVUUF9XMl9sbS5wKSkNCg0KYGBgDQoNCg0KIyMjIFBsb3QgUmV0ZW50aW9uIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpgYGB7cn0NCiMjU3VtbWFyeSBzdGF0aXN0aWNzIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpUb2xfU2NvcmVUUF9XMl9TRzwtc3VtbWFyeVNFKFRvbERhdGFfVzIsIG1lYXN1cmV2YXI9IlNjb3JlX1RQLnByb3AiLCBncm91cHZhcnM9YygiU2l0ZS5HZW5vIiwgIlNpdGUiLCAiR2Vub3R5cGUiKSwgbmEucm09VFJVRSkNCg0KIyNQbG90IEF2ZXJhZ2UgUmV0ZW50aW9uIGFjcm9zcyBUcmVhdG1lbnRzDQpUb2xfU2NvcmVUUF9XMl9TRy5wbG90PC1nZ3Bsb3QoVG9sX1Njb3JlVFBfVzJfU0csIGFlcyh4PVNpdGUuR2VubywgeT1TY29yZV9UUC5wcm9wLCBjb2xvdXI9R2Vub3R5cGUpKSArIA0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPVNjb3JlX1RQLnByb3Atc2UsIHltYXg9U2NvcmVfVFAucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeikrDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeikrIA0KICAgZ2d0aXRsZSgiQ29sb3IgUmV0ZW50aW9uIGJ5IFRpbWVwb2ludCIpKw0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKCBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksDQogICAgICAgIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIiksDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwgDQogICAgICAgIGxlZ2VuZC5kaXJlY3Rpb249Imhvcml6b250YWwiLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBwbG90LnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgaGp1c3QgPSAwLjUpKSsNCiAgbGFicyh4PSIiLCB5PSJQcm9wb3J0aW9uIFJldGFpbmVkIikrDQogIHlsaW0oMCwgMS41KSsgDQogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIiIsIktsZWluIiwiIiwiIiwiU29tZXRoaW5nIFNwZWNpYWwiLCIiKSkrDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBHZW5vLmNvbG9ycy5vKSsgDQogIHN0YXRfcHZhbHVlX21hbnVhbChkYXRhPVRvbF9TY29yZVRQX1cyX2xtLnAsICB5LnBvc2l0aW9uPTEsIHN0ZXAuaW5jcmVhc2U9MC40NSwgbGFiZWw9IlNpZyIsIGhpZGUubnM9VFJVRSk7IFRvbF9TY29yZVRQX1cyX1NHLnBsb3QNCg0KYGBgDQoNCg0KIyMgQ29sb3IgU2NvcmUgYnkgVGltZXBvaW50IFN1bW1lciAyIFRpbWVwb2ludCBNMQ0KDQojIyMgUnVuIE1vZGVsDQpgYGB7cn0NCiMjQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRvbERhdGFfTTEkU2NvcmVfVFAucHJvcCkNCnNoYXBpcm8udGVzdChUb2xEYXRhX00xJFNjb3JlX1RQLnByb3ApDQojTm90IG5vcm1hbA0KDQojI1RyeSBzcXVhcmUgdHJhbnNmb3JtYXRpb24NCmhpc3QoKFRvbERhdGFfTTEkU2NvcmVfVFAucHJvcCleMikNCnNoYXBpcm8udGVzdCgoVG9sRGF0YV9NMSRTY29yZV9UUC5wcm9wKV4yKQ0KI05vdCBub3JtYWwNCg0KIyNUcnkgY3ViZWQgdHJhbnNmb3JtYXRpb24NCmhpc3QoKFRvbERhdGFfTTEkU2NvcmVfVFAucHJvcCleMykNCnNoYXBpcm8udGVzdCgoVG9sRGF0YV9NMSRTY29yZV9UUC5wcm9wKV4zKQ0KI05vdCBub3JtYWwNCg0KIyNNb2RlbCBhcyBhIGZ1bmN0aW9uIG9mIFNpdGUgYW5kIEdlbm90eXBlDQojI01vZGVsIHdpdGggbm8gdHJhbnNmb3JtYXRpb24gYW5kIGNoZWNrIHJlc2lkdWFscw0KVG9sX1Njb3JlVFBfTTFfbG08LWxtKFNjb3JlX1RQLnByb3B+U2l0ZStHZW5vdHlwZStTaXRlOkdlbm90eXBlLCBkYXRhPVRvbERhdGFfTTEpDQoNCmBgYA0KDQoNCiMjIyMgQ2hlY2sgUmVzaWR1YWxzDQpgYGB7cn0NCiMjQ2hlY2sgTm9ybWFsaXR5IG9mIFJlc2lkdWFscw0KI0Rpc3RyaWJ1dGlvbiANCnBsb3QoZGVuc2l0eShyZXNpZChUb2xfU2NvcmVUUF9NMV9sbSkpKQ0KDQojUS1RIHBsb3QNCnFxbm9ybShyZXNpZChUb2xfU2NvcmVUUF9NMV9sbSkpOyBxcWxpbmUocmVzaWQoVG9sX1Njb3JlVFBfTTFfbG0pKQ0KDQojI0NoZWNrIFZhcmlhbmNlIG9mIFJlc2lkdWFscyBhY3Jvc3MgRml0dGVkIFZhbHVlcw0KcGxvdChmaXR0ZWQoVG9sX1Njb3JlVFBfTTFfbG0pLCByZXNpZChUb2xfU2NvcmVUUF9NMV9sbSkpDQoNCmBgYA0KDQoNCiMjIyBNb2RlbCBSZXN1bHRzDQoNCiMjIyMgT3ZlcmFsbA0KYGBge3J9DQojTW9kZWwgUmVzdWx0cw0Kc3VtbWFyeShUb2xfU2NvcmVUUF9NMV9sbSkNCmFub3ZhKFRvbF9TY29yZVRQX00xX2xtKQ0KDQojRWZmZWN0IFNpemUgb2YgUHJlZGljdG9ycw0KZXRhX3NxdWFyZWQoVG9sX1Njb3JlVFBfTTFfbG0sIHBhcnRpYWw9RkFMU0UpDQoNCiMjU2F2ZSBtb2RlbCByZXN1bHRzDQpUb2xfU2NvcmVUUF9NMV9sbS5yZXM8LWRhdGEuZnJhbWUoYW5vdmEoVG9sX1Njb3JlVFBfTTFfbG0pKQ0KVG9sX1Njb3JlVFBfTTFfbG0ucmVzJFByZWRpY3Rvcjwtcm93bmFtZXMoVG9sX1Njb3JlVFBfTTFfbG0ucmVzKQ0KVG9sX1Njb3JlVFBfTTFfbG0ucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9TY29yZVRQX00xX2xtLCBwYXJ0aWFsPUZBTFNFKSRFdGEyLCBOQSkNClRvbF9TY29yZVRQX00xX2xtLnJlcyRSZXNwb25zZTwtcmVwKCJDb2xvcl9UUCIsIG5yb3coVG9sX1Njb3JlVFBfTTFfbG0ucmVzKSkNClRvbF9TY29yZVRQX00xX2xtLnJlcyRUaW1lUDwtcmVwKCJNMSIsIG5yb3coVG9sX1Njb3JlVFBfTTFfbG0ucmVzKSkNClRvbF9TY29yZVRQX00xX2xtLnJlczwtVG9sX1Njb3JlVFBfTTFfbG0ucmVzICU+JSBkcGx5cjo6cmVuYW1lKCBwLnZhbHVlID0gIlByLi5GLiIsIERGPSAiRGYiKQ0KDQpgYGANCg0KU2lnbmlmaWNhbnQgZWZmZWN0IG9mIFNpdGUgYW5kIEdlbm90eXBlLiBTdGlsbCBjaGVja2luZyBTaXRlKkdlbm90eXBlIGZvciBjb21wYXJhYmlsaXR5IGFjcm9zcyBUaW1lcG9pbnRzLg0KDQoNCiMjIyMgUGFpcndpc2UNCmBgYHtyfQ0KI1BhaXJ3aXNlIGNvbXBhcmlzb25zIGFjcm9zczoNCg0KI0dlbm90eXBlcyB3aXRoaW4gU2l0ZXMNCmVtbWVhbnMoVG9sX1Njb3JlVFBfTTFfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNCmVtbWVhbnMoVG9sX1Njb3JlVFBfTTFfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkNCg0KIyNTYXZlIHAtdmFsdWVzDQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQpUb2xfU2NvcmVUUF9NMV9sbS5nZW5vPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1Njb3JlVFBfTTFfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkkY29udHJhc3RzKQ0KVG9sX1Njb3JlVFBfTTFfbG0uZ2VubzwtVG9sX1Njb3JlVFBfTTFfbG0uZ2VubyAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TY29yZVRQX00xX2xtLmdlbm8kZ3JvdXAxPC1wYXN0ZShUb2xfU2NvcmVUUF9NMV9sbS5nZW5vJFNpdGUsIFRvbF9TY29yZVRQX00xX2xtLmdlbm8kZ3JvdXAxLCBzZXA9Il8iKQ0KVG9sX1Njb3JlVFBfTTFfbG0uZ2VubyRncm91cDI8LXBhc3RlKFRvbF9TY29yZVRQX00xX2xtLmdlbm8kU2l0ZSwgVG9sX1Njb3JlVFBfTTFfbG0uZ2VubyRncm91cDIsIHNlcD0iXyIpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQpUb2xfU2NvcmVUUF9NMV9sbS5zaXRlPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1Njb3JlVFBfTTFfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkkY29udHJhc3RzKQ0KVG9sX1Njb3JlVFBfTTFfbG0uc2l0ZTwtVG9sX1Njb3JlVFBfTTFfbG0uc2l0ZSAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TY29yZVRQX00xX2xtLnNpdGUkZ3JvdXAxPC1wYXN0ZShUb2xfU2NvcmVUUF9NMV9sbS5zaXRlJGdyb3VwMSwgVG9sX1Njb3JlVFBfTTFfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNClRvbF9TY29yZVRQX00xX2xtLnNpdGUkZ3JvdXAyPC1wYXN0ZShUb2xfU2NvcmVUUF9NMV9sbS5zaXRlJGdyb3VwMiwgVG9sX1Njb3JlVFBfTTFfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNCg0KI0Z1bGwgbGlzdCBvZiBwLXZhbHVlcw0KVG9sX1Njb3JlVFBfTTFfbG0ucDwtcmJpbmQoVG9sX1Njb3JlVFBfTTFfbG0uZ2Vub1ssYygxOjIsNDo4KV0sIFRvbF9TY29yZVRQX00xX2xtLnNpdGVbLGMoMToyLDQ6OCldKQ0KVG9sX1Njb3JlVFBfTTFfbG0ucDwtVG9sX1Njb3JlVFBfTTFfbG0ucCAlPiUgZHBseXI6OnJlbmFtZSggcCA9IHAudmFsdWUpDQoNCiNBZGQgU2lnbmlmaWNhbmNlIExldmVscw0KVG9sX1Njb3JlVFBfTTFfbG0ucCRTaWc8LWlmZWxzZShUb2xfU2NvcmVUUF9NMV9sbS5wJHA8MC4wMDEsICIqKioiLCBpZmVsc2UoVG9sX1Njb3JlVFBfTTFfbG0ucCRwPDAuMDEsICIqKiIsIGlmZWxzZShUb2xfU2NvcmVUUF9NMV9sbS5wJHA8MC4wNSwgIioiLCBOQSkpKQ0KDQojU3BlY2lmeSBSZXNwb25zZSBhbmQgVGltZXBvaW50DQpUb2xfU2NvcmVUUF9NMV9sbS5wJFJlc3BvbnNlPC1yZXAoIkNvbG9yX1RQIiwgbnJvdyhUb2xfU2NvcmVUUF9NMV9sbS5wKSkNClRvbF9TY29yZVRQX00xX2xtLnAkVGltZVA8LXJlcCgiTTEiLCBucm93KFRvbF9TY29yZVRQX00xX2xtLnApKQ0KDQpgYGANCg0KDQojIyMgUGxvdCBSZXRlbnRpb24gYnkgU2l0ZSBhbmQgR2Vub3R5cGUNCmBgYHtyfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgR2Vub3R5cGUNClRvbF9TY29yZVRQX00xX1NHPC1zdW1tYXJ5U0UoVG9sRGF0YV9NMSwgbWVhc3VyZXZhcj0iU2NvcmVfVFAucHJvcCIsIGdyb3VwdmFycz1jKCJTaXRlLkdlbm8iLCAiU2l0ZSIsICJHZW5vdHlwZSIpLCBuYS5ybT1UUlVFKQ0KDQojI1Bsb3QgQXZlcmFnZSBSZXRlbnRpb24gYWNyb3NzIFRyZWF0bWVudHMNClRvbF9TY29yZVRQX00xX1NHLnBsb3Q8LWdncGxvdChUb2xfU2NvcmVUUF9NMV9TRywgYWVzKHg9U2l0ZS5HZW5vLCB5PVNjb3JlX1RQLnByb3AsIGNvbG91cj1HZW5vdHlwZSkpICsgDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49U2NvcmVfVFAucHJvcC1zZSwgeW1heD1TY29yZV9UUC5wcm9wK3NlKSwgd2lkdGg9Y2FwLnN6LCBsaW5ld2lkdGg9YmFyLnN6KSsNCiAgZ2VvbV9wb2ludChzaXplPXBvaW50LnN6KSsgDQogICBnZ3RpdGxlKCJDb2xvciBSZXRlbnRpb24gYnkgVGltZXBvaW50IikrDQogIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCANCiAgICAgICAgbGVnZW5kLmRpcmVjdGlvbj0iaG9yaXpvbnRhbCIsDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IlByb3BvcnRpb24gUmV0YWluZWQiKSsNCiB5bGltKDAsIDEuNSkrIA0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIiLCJLbGVpbiIsIiIsIiIsIlNvbWV0aGluZyBTcGVjaWFsIiwiIikpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gR2Vuby5jb2xvcnMubykrIA0KICBzdGF0X3B2YWx1ZV9tYW51YWwoZGF0YT1Ub2xfU2NvcmVUUF9NMV9sbS5wLCAgeS5wb3NpdGlvbj0xLjA1LCBzdGVwLmluY3JlYXNlPTAuMywgbGFiZWw9IlNpZyIsIGhpZGUubnM9VFJVRSk7IFRvbF9TY29yZVRQX00xX1NHLnBsb3QNCg0KYGBgDQoNCg0KIyMgQ29sb3IgU2NvcmUgYnkgVGltZXBvaW50IFdpbnRlciBUaW1lcG9pbnQgTTQNCg0KIyMjIFJ1biBNb2RlbA0KYGBge3J9DQojI0NoZWNrIG5vcm1hbGl0eQ0KaGlzdChUb2xEYXRhX000JFNjb3JlX1RQLnByb3ApDQpzaGFwaXJvLnRlc3QoVG9sRGF0YV9NNCRTY29yZV9UUC5wcm9wKQ0KI05vdCBOb3JtYWwNCg0KIyNUcnkgc3F1YXJlIHRyYW5zZm9ybWF0aW9uDQpoaXN0KChUb2xEYXRhX000JFNjb3JlX1RQLnByb3ApXjIpDQpzaGFwaXJvLnRlc3QoKFRvbERhdGFfTTQkU2NvcmVfVFAucHJvcCleMikNCiNOb3QgTm9ybWFsDQoNCiMjVHJ5IGN1YmVkIHRyYW5zZm9ybWF0aW9uDQpoaXN0KChUb2xEYXRhX000JFNjb3JlX1RQLnByb3ApXjMpDQpzaGFwaXJvLnRlc3QoKFRvbERhdGFfTTQkU2NvcmVfVFAucHJvcCleMykNCiNOb3QgTm9ybWFsDQoNCiMjTW9kZWwgYXMgYSBmdW5jdGlvbiBvZiBTaXRlIGFuZCBHZW5vdHlwZQ0KIyNNb2RlbCB3aXRoIG5vIHRyYW5zZm9ybWF0aW9uIGFuZCBjaGVjayByZXNpZHVhbHMNClRvbF9TY29yZVRQX000X2xtPC1sbShTY29yZV9UUC5wcm9wflNpdGUrR2Vub3R5cGUrU2l0ZTpHZW5vdHlwZSwgZGF0YT1Ub2xEYXRhX000KQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX1Njb3JlVFBfTTRfbG0pKSkNCg0KI1EtUSBwbG90DQpxcW5vcm0ocmVzaWQoVG9sX1Njb3JlVFBfTTRfbG0pKTsgcXFsaW5lKHJlc2lkKFRvbF9TY29yZVRQX000X2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9TY29yZVRQX000X2xtKSwgcmVzaWQoVG9sX1Njb3JlVFBfTTRfbG0pKQ0KDQpgYGANCg0KDQojIyMgTW9kZWwgUmVzdWx0cw0KDQojIyMjIE92ZXJhbGwNCmBgYHtyfQ0KI01vZGVsIFJlc3VsdHMNCnN1bW1hcnkoVG9sX1Njb3JlVFBfTTRfbG0pDQphbm92YShUb2xfU2NvcmVUUF9NNF9sbSkNCg0KI0VmZmVjdCBTaXplIG9mIFByZWRpY3RvcnMNCmV0YV9zcXVhcmVkKFRvbF9TY29yZVRQX000X2xtLCBwYXJ0aWFsPUZBTFNFKQ0KDQojI1NhdmUgbW9kZWwgcmVzdWx0cw0KVG9sX1Njb3JlVFBfTTRfbG0ucmVzPC1kYXRhLmZyYW1lKGFub3ZhKFRvbF9TY29yZVRQX000X2xtKSkNClRvbF9TY29yZVRQX000X2xtLnJlcyRQcmVkaWN0b3I8LXJvd25hbWVzKFRvbF9TY29yZVRQX000X2xtLnJlcykNClRvbF9TY29yZVRQX000X2xtLnJlcyRFdGFTcTwtYyhldGFfc3F1YXJlZChUb2xfU2NvcmVUUF9NNF9sbSwgcGFydGlhbD1GQUxTRSkkRXRhMiwgTkEpDQpUb2xfU2NvcmVUUF9NNF9sbS5yZXMkUmVzcG9uc2U8LXJlcCgiQ29sb3JfVFAiLCBucm93KFRvbF9TY29yZVRQX000X2xtLnJlcykpDQpUb2xfU2NvcmVUUF9NNF9sbS5yZXMkVGltZVA8LXJlcCgiTTQiLCBucm93KFRvbF9TY29yZVRQX000X2xtLnJlcykpDQpUb2xfU2NvcmVUUF9NNF9sbS5yZXM8LVRvbF9TY29yZVRQX000X2xtLnJlcyAlPiUgZHBseXI6OnJlbmFtZSggcC52YWx1ZSA9ICJQci4uRi4iLCBERj0gIkRmIikNCg0KYGBgDQoNClNpZ25pZmljYW50IGVmZmVjdCBvZiBHZW5vdHlwZS4gU3RpbGwgY2hlY2tpbmcgU2l0ZSpHZW5vdHlwZSBmb3IgY29tcGFyYWJpbGl0eSBhY3Jvc3MgVGltZXBvaW50cy4NCg0KDQoNCiMjIyMgUGFpcndpc2UNCmBgYHtyfQ0KI1BhaXJ3aXNlIGNvbXBhcmlzb25zIGFjcm9zczoNCg0KI0dlbm90eXBlcyB3aXRoaW4gU2l0ZXMNCmVtbWVhbnMoVG9sX1Njb3JlVFBfTTRfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNCmVtbWVhbnMoVG9sX1Njb3JlVFBfTTRfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkNCg0KIyNTYXZlIHAtdmFsdWVzDQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQpUb2xfU2NvcmVUUF9NNF9sbS5nZW5vPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1Njb3JlVFBfTTRfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkkY29udHJhc3RzKQ0KVG9sX1Njb3JlVFBfTTRfbG0uZ2VubzwtVG9sX1Njb3JlVFBfTTRfbG0uZ2VubyAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TY29yZVRQX000X2xtLmdlbm8kZ3JvdXAxPC1wYXN0ZShUb2xfU2NvcmVUUF9NNF9sbS5nZW5vJFNpdGUsIFRvbF9TY29yZVRQX000X2xtLmdlbm8kZ3JvdXAxLCBzZXA9Il8iKQ0KVG9sX1Njb3JlVFBfTTRfbG0uZ2VubyRncm91cDI8LXBhc3RlKFRvbF9TY29yZVRQX000X2xtLmdlbm8kU2l0ZSwgVG9sX1Njb3JlVFBfTTRfbG0uZ2VubyRncm91cDIsIHNlcD0iXyIpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQpUb2xfU2NvcmVUUF9NNF9sbS5zaXRlPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1Njb3JlVFBfTTRfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkkY29udHJhc3RzKQ0KVG9sX1Njb3JlVFBfTTRfbG0uc2l0ZTwtVG9sX1Njb3JlVFBfTTRfbG0uc2l0ZSAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TY29yZVRQX000X2xtLnNpdGUkZ3JvdXAxPC1wYXN0ZShUb2xfU2NvcmVUUF9NNF9sbS5zaXRlJGdyb3VwMSwgVG9sX1Njb3JlVFBfTTRfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNClRvbF9TY29yZVRQX000X2xtLnNpdGUkZ3JvdXAyPC1wYXN0ZShUb2xfU2NvcmVUUF9NNF9sbS5zaXRlJGdyb3VwMiwgVG9sX1Njb3JlVFBfTTRfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNCg0KI0Z1bGwgbGlzdCBvZiBwLXZhbHVlcw0KVG9sX1Njb3JlVFBfTTRfbG0ucDwtcmJpbmQoVG9sX1Njb3JlVFBfTTRfbG0uZ2Vub1ssYygxOjIsNDo4KV0sIFRvbF9TY29yZVRQX000X2xtLnNpdGVbLGMoMToyLDQ6OCldKQ0KVG9sX1Njb3JlVFBfTTRfbG0ucDwtVG9sX1Njb3JlVFBfTTRfbG0ucCAlPiUgZHBseXI6OnJlbmFtZSggcCA9IHAudmFsdWUpDQoNCiNBZGQgU2lnbmlmaWNhbmNlIExldmVscw0KVG9sX1Njb3JlVFBfTTRfbG0ucCRTaWc8LWlmZWxzZShUb2xfU2NvcmVUUF9NNF9sbS5wJHA8MC4wMDEsICIqKioiLCBpZmVsc2UoVG9sX1Njb3JlVFBfTTRfbG0ucCRwPDAuMDEsICIqKiIsIGlmZWxzZShUb2xfU2NvcmVUUF9NNF9sbS5wJHA8MC4wNSwgIioiLCBOQSkpKQ0KDQojU3BlY2lmeSBSZXNwb25zZSBhbmQgVGltZXBvaW50DQpUb2xfU2NvcmVUUF9NNF9sbS5wJFJlc3BvbnNlPC1yZXAoIkNvbG9yX1RQIiwgbnJvdyhUb2xfU2NvcmVUUF9NNF9sbS5wKSkNClRvbF9TY29yZVRQX000X2xtLnAkVGltZVA8LXJlcCgiTTQiLCBucm93KFRvbF9TY29yZVRQX000X2xtLnApKQ0KDQpgYGANCg0KDQojIyMgUGxvdCBSZXRlbnRpb24gYnkgU2l0ZSBhbmQgR2Vub3R5cGUNCmBgYHtyfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgR2Vub3R5cGUNClRvbF9TY29yZVRQX000X1NHPC1zdW1tYXJ5U0UoVG9sRGF0YV9NNCwgbWVhc3VyZXZhcj0iU2NvcmVfVFAucHJvcCIsIGdyb3VwdmFycz1jKCJTaXRlLkdlbm8iLCAiU2l0ZSIsICJHZW5vdHlwZSIpLCBuYS5ybT1UUlVFKQ0KDQojI1Bsb3QgQXZlcmFnZSBSZXRlbnRpb24gYWNyb3NzIFRyZWF0bWVudHMNClRvbF9TY29yZVRQX000X1NHLnBsb3Q8LWdncGxvdChUb2xfU2NvcmVUUF9NNF9TRywgYWVzKHg9U2l0ZS5HZW5vLCB5PVNjb3JlX1RQLnByb3AsIGNvbG91cj1HZW5vdHlwZSkpICsgDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49U2NvcmVfVFAucHJvcC1zZSwgeW1heD1TY29yZV9UUC5wcm9wK3NlKSwgd2lkdGg9Y2FwLnN6LCBsaW5ld2lkdGg9YmFyLnN6KSsNCiAgZ2VvbV9wb2ludChzaXplPXBvaW50LnN6KSsgDQogICBnZ3RpdGxlKCJDb2xvciBSZXRlbnRpb24gYnkgVGltZXBvaW50IikrDQogIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCANCiAgICAgICAgbGVnZW5kLmRpcmVjdGlvbj0iaG9yaXpvbnRhbCIsDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IlByb3BvcnRpb24gUmV0YWluZWQiKSsNCiAgeWxpbSgwLCAxLjUpKyANCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiIiwiS2xlaW4iLCIiLCIiLCJTb21ldGhpbmcgU3BlY2lhbCIsIiIpKSsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IEdlbm8uY29sb3JzLm8pKyANCiAgc3RhdF9wdmFsdWVfbWFudWFsKGRhdGE9VG9sX1Njb3JlVFBfTTRfbG0ucCwgIHkucG9zaXRpb249MS4xLCBzdGVwLmluY3JlYXNlPTAuNCwgbGFiZWw9IlNpZyIsIGhpZGUubnM9VFJVRSk7IFRvbF9TY29yZVRQX000X1NHLnBsb3QNCg0KYGBgDQoNCg0KIyBDb250cmFzdHMgQWNyb3NzIE1ldHJpY3MNCg0KIyMjIENvbWJpbmUgQ29udHJhc3QgUmVzdWx0cw0KQ3JlYXRpbmcgYSBoZWF0bWFwIHRvIGNvbXBhcmUgdGhlIGRpcmVjdGlvbiBhbmQgc2lnbmlmaWNhbmNlIG9mIHBhaXJ3aXNlIGNvbXBhcmlzb25zIGFjcm9zcyBUb2xlcmFuY2UgbWV0cmljcy4gUG9zaXRpdmUgZXN0aW1hdGVzIGluZGljYXRlIHRoYXQgR3JvdXAgMSA+IEdyb3VwIDIuIFAgdmFsdWVzIG9mIGxlc3MgdGhhbiAwLjA1IGFyZSBjb25zaWRlcmVkIHNpZ25pZmljYW50LiAgIA0KYGBge3J9DQojI0NvbWJpbmUgUmVzdWx0cw0KVG9sX2NvbnRyYXN0czwtcmJpbmQoVG9sX0NobF9XMl9sbS5wLCBUb2xfQ2hsX00xX2xtLnAsIFRvbF9DaGxfTTRfbG0ucCwgDQogICAgICAgICAgICAgICAgICAgICBUb2xfU3ltX1cyX2xtLnAsIFRvbF9TeW1fTTFfbG0ucCwgVG9sX1N5bV9NNF9sbS5wLCANCiAgICAgICAgICAgICAgICAgICAgIFRvbF9TY29yZUZfVzJfbG0ucCwgVG9sX1Njb3JlRl9NMV9sbS5wLCBUb2xfU2NvcmVGX000X2xtLnAsIA0KICAgICAgICAgICAgICAgICAgICAgVG9sX1Njb3JlVFBfVzJfbG0ucCwgVG9sX1Njb3JlVFBfTTFfbG0ucCwgVG9sX1Njb3JlVFBfTTRfbG0ucCkNCg0KIyNDcmVhdGUgQ29udHJhc3QgQ29sdW1uDQpUb2xfY29udHJhc3RzJENvbnRyYXN0PC1wYXN0ZShUb2xfY29udHJhc3RzJGdyb3VwMSwgVG9sX2NvbnRyYXN0cyRncm91cDIsIHNlcD0iIHYuICIpDQoNCiMjQWRkIFNldCBjb2x1bW4gd2l0aCBDb250cmFzdCBhbmQgVGltZXBvaW50DQpUb2xfY29udHJhc3RzJFNldDwtcGFzdGUoVG9sX2NvbnRyYXN0cyRUaW1lUCwgVG9sX2NvbnRyYXN0cyRDb250cmFzdCwgc2VwPSIgIikNCg0KIyNSZS1vcmRlciBieSBTZWFzb25hbCBUaW1lcG9pbnQNClRvbF9jb250cmFzdHMkVGltZVA8LWZhY3RvcihUb2xfY29udHJhc3RzJFRpbWVQLCBsZXZlbHM9YygiVzIiLCAiTTEiLCAiTTQiKSwgb3JkZXJlZD1UUlVFKQ0KVG9sX2NvbnRyYXN0czwtIFRvbF9jb250cmFzdHMgJT4lIGFycmFuZ2UoZGVzYyhhcy5udW1lcmljKFRpbWVQKSkpDQoNClRvbF9jb250cmFzdHMkU2V0PC1mYWN0b3IoVG9sX2NvbnRyYXN0cyRTZXQsIGxldmVscz1jKHVuaXF1ZShUb2xfY29udHJhc3RzJFNldCkpLCBvcmRlcmVkPVRSVUUpDQpgYGANCg0KDQojIyMgU3RhbmRhcmRpemUgUmVzcG9uc2UgU2NhbGUNCkNvbnZlcnQgRXN0aW1hdGUgdG8gdGhlIFJlc3BvbnNlIHNjYWxlIChpbnN0ZWFkIG9mIGxvZyArMSBzY2FsZSkgZm9yIG1vZGVscyB3aGVyZSB0aGUgcmVzcG9uc2Ugd2FzIGxvZyB0cmFuc2Zvcm1lZA0KYGBge3J9DQpUb2xfY29udHJhc3RzJEVzdGltYXRlPC1Ub2xfY29udHJhc3RzJGVzdGltYXRlDQoNCiNDaGwgTTQNClRvbF9jb250cmFzdHMkRXN0aW1hdGVbd2hpY2goVG9sX2NvbnRyYXN0cyRSZXNwb25zZT09IkNobG9yb3BoeWxsIiAmIFRvbF9jb250cmFzdHMkVGltZVA9PSJNNCIpXTwtYyhleHAoVG9sX2NvbnRyYXN0cyRlc3RpbWF0ZVt3aGljaChUb2xfY29udHJhc3RzJFJlc3BvbnNlPT0iQ2hsb3JvcGh5bGwiICYgVG9sX2NvbnRyYXN0cyRUaW1lUD09Ik00IildKS0xKQ0KDQojU3ltIE0xDQpUb2xfY29udHJhc3RzJEVzdGltYXRlW3doaWNoKFRvbF9jb250cmFzdHMkUmVzcG9uc2U9PSJTeW1iaW9udHMiICYgVG9sX2NvbnRyYXN0cyRUaW1lUD09Ik0xIildPC1jKGV4cChUb2xfY29udHJhc3RzJGVzdGltYXRlW3doaWNoKFRvbF9jb250cmFzdHMkUmVzcG9uc2U9PSJTeW1iaW9udHMiICYgVG9sX2NvbnRyYXN0cyRUaW1lUD09Ik0xIildKS0xKQ0KDQoNCmBgYA0KDQoNCiMjIENvbnRyYXN0IEhlYXRtYXBzDQoNCiMjIyBTdW1tZXIgMSBUaW1lcG9pbnQgVzINCmBgYHtyfQ0KVG9sX1BhaXJzX1cyLnBsb3Q8LWdncGxvdChkYXRhPVRvbF9jb250cmFzdHNbd2hpY2goVG9sX2NvbnRyYXN0cyRUaW1lUD09IlcyIiksXSwgYWVzKHg9UmVzcG9uc2UsIHk9Q29udHJhc3QsIGZpbGw9RXN0aW1hdGUpKSsNCiAgZ2VvbV90aWxlKCkrDQogIGdlb21fdGV4dChhZXMobGFiZWw9U2lnKSwgc2l6ZT1zaWcuc3opKw0KICBzY2FsZV9maWxsX2dyYWRpZW50Mihsb3c9IiNCQTFFMDJGRiIsIG1pZD0id2hpdGUiLCBoaWdoPSIjM0JBMEZERkYiKSsNCiAgdGhlbWVfYncoKSsNCiAgZ2d0aXRsZSgiUGFpcndpc2UgQ29udHJhc3RzIFN1bW1lciAxIikrDQogIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBhbmdsZT00NSwgaGp1c3Q9MSksDQogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LTEsIGNvbG91cj0iYmxhY2siKSwNCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksDQogICAgICAgIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gcGxvdC50aXRsZS5zeiwgY29sb3VyPSJibGFjayIsIGhqdXN0ID0gMC41KSkrDQogIGxhYnMoeD0iIiwgeT0iIiwgZmlsbD0iRXN0aW1hdGUiKTtUb2xfUGFpcnNfVzIucGxvdA0KYGBgDQoNCg0KIyMjIFN1bW1lciAyIFRpbWVwb2ludCBNMQ0KYGBge3J9DQpUb2xfUGFpcnNfTTEucGxvdDwtZ2dwbG90KGRhdGE9VG9sX2NvbnRyYXN0c1t3aGljaChUb2xfY29udHJhc3RzJFRpbWVQPT0iTTEiKSxdLCBhZXMoeD1SZXNwb25zZSwgeT1Db250cmFzdCwgZmlsbD1Fc3RpbWF0ZSkpKw0KICBnZW9tX3RpbGUoKSsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1TaWcpLCBzaXplPXNpZy5zeikrDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKGxvdz0iI0JBMUUwMkZGIiwgbWlkPSJ3aGl0ZSIsIGhpZ2g9IiMzQkEwRkRGRiIpKw0KICB0aGVtZV9idygpKw0KICBnZ3RpdGxlKCJQYWlyd2lzZSBDb250cmFzdHMgU3VtbWVyIDIiKSsNCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50aXRsZS5zeiwgY29sb3VyPSJibGFjayIsIGFuZ2xlPTQ1LCBoanVzdD0xKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3otMSwgY29sb3VyPSJibGFjayIpLA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBwbG90LnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgaGp1c3QgPSAwLjUpKSsNCiAgbGFicyh4PSIiLCB5PSIiLCBmaWxsPSJFc3RpbWF0ZSIpO1RvbF9QYWlyc19NMS5wbG90DQpgYGANCg0KDQojIyMgV2ludGVyIFRpbWVwb2ludCBNNA0KYGBge3J9DQpUb2xfUGFpcnNfTTQucGxvdDwtZ2dwbG90KGRhdGE9VG9sX2NvbnRyYXN0c1t3aGljaChUb2xfY29udHJhc3RzJFRpbWVQPT0iTTQiKSxdLCBhZXMoeD1SZXNwb25zZSwgeT1Db250cmFzdCwgZmlsbD1Fc3RpbWF0ZSkpKw0KICBnZW9tX3RpbGUoKSsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1TaWcpLCBzaXplPXNpZy5zeikrDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKGxvdz0iI0JBMUUwMkZGIiwgbWlkPSJ3aGl0ZSIsIGhpZ2g9IiMzQkEwRkRGRiIpKw0KICB0aGVtZV9idygpKw0KICBnZ3RpdGxlKCJQYWlyd2lzZSBDb250cmFzdHMgTW9udGggNCIpKw0KICB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgYW5nbGU9NDUsIGhqdXN0PTEpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zei0xLCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLA0KICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IiIsIGZpbGw9IkVzdGltYXRlIik7VG9sX1BhaXJzX000LnBsb3QNCmBgYA0KDQoNCiMjIyBBbGwgVGltZXBvaW50cw0KYGBge3J9DQpUb2xfUGFpcnMucGxvdDwtZ2dwbG90KGRhdGE9VG9sX2NvbnRyYXN0cywgYWVzKHg9UmVzcG9uc2UsIHk9U2V0LCBmaWxsPUVzdGltYXRlKSkrDQogIGdlb21fdGlsZSgpKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsPVNpZyksIHNpemU9c2lnLnN6KSsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudDIobG93PSIjQkExRTAyRkYiLCBtaWQ9IndoaXRlIiwgaGlnaD0iIzNCQTBGREZGIikrDQogIHRoZW1lX2J3KCkrDQogIGdndGl0bGUoIlBhaXJ3aXNlIENvbnRyYXN0cyIpKw0KICB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgYW5nbGU9NDUsIGhqdXN0PTEpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zei0xLCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLA0KICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IiIsIGZpbGw9IkVzdGltYXRlIik7VG9sX1BhaXJzLnBsb3QNCmBgYA0KDQoNCiMjIyBTaWduaWZpY2FudCBEaWZmZXJlbmNlcw0KDQpTdWJzZXR0aW5nIENvbnRyYXN0cyB0byBvbmx5IGluY2x1ZGUgY29udHJhc3RzIHdpdGggc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMgaW4gYXQgbGVhc3Qgb25lIG9mIHRoZSB0aGVybWFsIHRvbGVyYW5jZSBtZXRyaWNzIChDaGxvcm9waHlsbCBvciBTeW1iaW9udCBvciBDb2xvciByZXRlbnRpb24pDQpgYGB7cn0NCiMjUmVtb3ZlIHJvd3Mgd2l0aCBub24tc2lnbmlmaWNhbnQgcC12YWx1ZXMNClRvbF9jb250cmFzdHNfc2lnPC1zdWJzZXQoVG9sX2NvbnRyYXN0cywgcCA8IDAuMDUpDQoNCiMjS2VlcCBTZXRzIHdoZXJlIGF0IGxlYXN0IG9uZSBtZXRyaWMgc2hvd3MgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlDQpUb2xfU2V0c19zaWc8LWRhdGEuZnJhbWUoU2V0PWModW5pcXVlKFRvbF9jb250cmFzdHNfc2lnJFNldCkpKQ0KVG9sX2NvbnRyYXN0c19zaWdfU2V0PC1tZXJnZShUb2xfU2V0c19zaWcsIFRvbF9jb250cmFzdHMsIGFsbC54PVRSVUUsIGFsbC55PUZBTFNFKQ0KDQpgYGANCg0KDQpgYGB7cn0NClRvbF9QYWlyc19zaWcucGxvdDwtZ2dwbG90KGRhdGE9VG9sX2NvbnRyYXN0c19zaWdfU2V0LCBhZXMoeD1SZXNwb25zZSwgeT1TZXQsIGZpbGw9RXN0aW1hdGUpKSsNCiAgZ2VvbV90aWxlKCkrDQogIGdlb21fdGV4dChhZXMobGFiZWw9U2lnKSwgc2l6ZT1zaWcuc3opKw0KICBzY2FsZV9maWxsX2dyYWRpZW50Mihsb3c9IiNCQTFFMDJGRiIsIG1pZD0id2hpdGUiLCBoaWdoPSIjM0JBMEZERkYiKSsNCiAgdGhlbWVfYncoKSsNCiAgZ2d0aXRsZSgiU2lnbmlmaWNhbnQgUGFpcndpc2UgQ29udHJhc3RzIikrDQogIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBhbmdsZT00NSwgaGp1c3Q9MSksDQogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LTEsIGNvbG91cj0iYmxhY2siKSwNCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksDQogICAgICAgIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gcGxvdC50aXRsZS5zeiwgY29sb3VyPSJibGFjayIsIGhqdXN0ID0gMC41KSkrDQogIGxhYnMoeD0iIiwgeT0iIiwgZmlsbD0iRXN0aW1hdGUiKTtUb2xfUGFpcnNfc2lnLnBsb3QNCmBgYA0KDQoNCiMgRmlndXJlcw0KDQojIyMgRmlndXJlIFMyIFRvbGVyYW5jZSBBY3Jvc3MgTWV0cmljcw0KYGBge3J9DQojI0NyZWF0ZSBQYW5lbA0KVG9sZXJhbmNlX2ZpZzwtcGxvdF9ncmlkKFRvbF9DaGxfVzJfU0cucGxvdCwgVG9sX0NobF9NMV9TRy5wbG90LCBUb2xfQ2hsX000X1NHLnBsb3QsDQogICAgICAgICAgICAgICAgICBUb2xfU2NvcmVGX1cyX1NHLnBsb3QsIFRvbF9TY29yZUZfTTFfU0cucGxvdCwgVG9sX1Njb3JlRl9NNF9TRy5wbG90LA0KICAgICAgICAgICAgICAgICAgVG9sX1Njb3JlVFBfVzJfU0cucGxvdCwgVG9sX1Njb3JlVFBfTTFfU0cucGxvdCwgVG9sX1Njb3JlVFBfTTRfU0cucGxvdCwNCiAgICAgICAgICAgICAgICAgIFRvbF9TeW1fVzJfU0cucGxvdCwgVG9sX1N5bV9NMV9TRy5wbG90LCBUb2xfU3ltX000X1NHLnBsb3QsDQogICAgICAgICAgICAgICAgICAgICAgICBucm93PTQsIG5jb2w9MywgDQogICAgICAgICAgICAgICAgICAgICAgICByZWxfd2lkdGhzPTEsDQogICAgICAgICAgICAgICAgICAgICAgICByZWxfaGVpZ2h0cz0xLCANCiAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKCJBIiwgIkIiLCAiQyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkQiLCAiRSIsICJGIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRyIsICJIIiwgIkkiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJKIiwgIksiLCAiTCIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsX3NpemU9cGFuZWwubGFiLnN6LCANCiAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsX2ZvbnRmYWNlID0gImJvbGQiKQ0KDQojI1NhdmUgRmlndXJlDQpnZ3NhdmUoZmlsZW5hbWU9IkZpZ3VyZXMvRmlndXJlUzJfVG9sZXJhbmNlX0Fjcm9zc19NZXRyaWNzLnBuZyIsIHBsb3Q9VG9sZXJhbmNlX2ZpZywgZHBpPTMwMCwgd2lkdGg9MTgsIGhlaWdodD0yNCwgdW5pdHM9ImluIikNCg0KYGBgDQoNCg0KIyMjIEZpZ3VyZSAzIENvbnRyYXN0cyBIZWF0bWFwDQpgYGB7cn0NCiMjU2F2ZSBGaWd1cmUNCmdnc2F2ZShmaWxlbmFtZT0iRmlndXJlcy9GaWd1cmUzX1RvbGVyYW5jZV9IZWF0bWFwLnBuZyIsIHBsb3Q9VG9sX1BhaXJzLnBsb3QsIGRwaT0zMDAsIHdpZHRoPTgsIGhlaWdodD0xMiwgdW5pdHM9ImluIikNCg0KYGBgDQoNCg0KIyBUYWJsZXMNCg0KIyMjIExpbmVhciBNb2RlbCBSZXN1bHRzDQpgYGB7cn0NCiMjQ29tYmluZSBSZXN1bHRzIFRhYmxlcw0KVGFibGVTMl9Ub2wubG0ucmVzPC1yYmluZChUb2xfQ2hsX1cyX2xtLnJlcywgVG9sX0NobF9NMV9sbS5yZXMsIFRvbF9DaGxfTTRfbG0ucmVzLA0KICAgICAgICAgICAgICAgICAgICAgICAgVG9sX1N5bV9XMl9sbS5yZXMsIFRvbF9TeW1fTTFfbG0ucmVzLCBUb2xfU3ltX000X2xtLnJlcywNCiAgICAgICAgICAgICAgICAgICAgICAgIFRvbF9TY29yZUZfVzJfbG0ucmVzLCBUb2xfU2NvcmVGX00xX2xtLnJlcywgVG9sX1Njb3JlRl9NNF9sbS5yZXMsDQogICAgICAgICAgICAgICAgICAgIFRvbF9TY29yZVRQX1cyX2xtLnJlcywgVG9sX1Njb3JlVFBfTTFfbG0ucmVzLCBUb2xfU2NvcmVUUF9NNF9sbS5yZXMpDQoNCiMjT3JnYW5pemUNCm5hbWVzKFRhYmxlUzJfVG9sLmxtLnJlcykNClRhYmxlUzJfVG9sLmxtLnJlczwtVGFibGVTMl9Ub2wubG0ucmVzWyxjKCJUaW1lUCIsICJSZXNwb25zZSIsICJQcmVkaWN0b3IiLCAiREYiLCAiU3VtLlNxIiwgIk1lYW4uU3EiLCAiRi52YWx1ZSIsICJwLnZhbHVlIiwgIkV0YVNxIildDQoNCiNSb3VuZCB0byA0IGRpZ2l0cw0KVGFibGVTMl9Ub2wubG0ucmVzJFN1bS5TcTwtcm91bmQoVGFibGVTMl9Ub2wubG0ucmVzJFN1bS5TcSwgNCkNClRhYmxlUzJfVG9sLmxtLnJlcyRNZWFuLlNxPC1yb3VuZChUYWJsZVMyX1RvbC5sbS5yZXMkTWVhbi5TcSwgNCkNClRhYmxlUzJfVG9sLmxtLnJlcyRGLnZhbHVlPC1yb3VuZChUYWJsZVMyX1RvbC5sbS5yZXMkRi52YWx1ZSwgNCkNClRhYmxlUzJfVG9sLmxtLnJlcyRwLnZhbHVlPC1yb3VuZChUYWJsZVMyX1RvbC5sbS5yZXMkcC52YWx1ZSwgNCkNClRhYmxlUzJfVG9sLmxtLnJlcyRFdGFTcTwtcm91bmQoVGFibGVTMl9Ub2wubG0ucmVzJEV0YVNxLCA0KQ0KDQojI1dyaXRlIE91dCBUYWJsZQ0Kd3JpdGUuY3N2KFRhYmxlUzJfVG9sLmxtLnJlcywgIlRhYmxlcy9UYWJsZVMyX1RvbGVyYW5jZV9MTV9SZXN1bHRzLmNzdiIsIHJvdy5uYW1lcz1GQUxTRSkNCg0KYGBgDQoNCg0KIyMjIFBhaXJ3aXNlIENvbXBhcmlzb24gUmVzdWx0cw0KYGBge3J9DQojI1BhaXJ3aXNlIFJlc3VsdHMgVGFibGUNClRhYmxlUzNfVG9sLnBhaXJ3aXNlPC1Ub2xfY29udHJhc3RzDQoNCiMjT3JnYW5pemUNCm5hbWVzKFRhYmxlUzNfVG9sLnBhaXJ3aXNlKQ0KVGFibGVTM19Ub2wucGFpcndpc2U8LVRhYmxlUzNfVG9sLnBhaXJ3aXNlWyxjKCJUaW1lUCIsICJSZXNwb25zZSIsICJDb250cmFzdCIsICJFc3RpbWF0ZSIsICJTRSIsICJkZiIsICJ0LnJhdGlvIiwgInAiKV0NClRhYmxlUzNfVG9sLnBhaXJ3aXNlPC1UYWJsZVMzX1RvbC5wYWlyd2lzZSAlPiUgZHBseXI6OnJlbmFtZSggREYgPSBkZikgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSBwKQ0KDQojUm91bmQgdG8gNCBkaWdpdHMNClRhYmxlUzNfVG9sLnBhaXJ3aXNlJEVzdGltYXRlPC1yb3VuZChUYWJsZVMzX1RvbC5wYWlyd2lzZSRFc3RpbWF0ZSwgNCkNClRhYmxlUzNfVG9sLnBhaXJ3aXNlJFNFPC1yb3VuZChUYWJsZVMzX1RvbC5wYWlyd2lzZSRTRSwgNCkNClRhYmxlUzNfVG9sLnBhaXJ3aXNlJHQucmF0aW88LXJvdW5kKFRhYmxlUzNfVG9sLnBhaXJ3aXNlJHQucmF0aW8sIDQpDQpUYWJsZVMzX1RvbC5wYWlyd2lzZSRwLnZhbHVlPC1yb3VuZChUYWJsZVMzX1RvbC5wYWlyd2lzZSRwLnZhbHVlLCA0KQ0KDQojI1dyaXRlIE91dCBUYWJsZQ0Kd3JpdGUuY3N2KFRhYmxlUzNfVG9sLnBhaXJ3aXNlLCAiVGFibGVzL1RhYmxlUzNfVG9sZXJhbmNlX1BhaXJ3aXNlX1Jlc3VsdHMuY3N2Iiwgcm93Lm5hbWVzPUZBTFNFKQ0KYGBgDQoNCg==